Created
December 12, 2020 22:18
-
-
Save gswallow/0b9d1728948129a6199feccf9849d7f6 to your computer and use it in GitHub Desktop.
AWS: Generate a monthly-bill-by-account PDF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import boto3 | |
import math | |
from io import BytesIO | |
from pdfdocument.document import PDFDocument | |
start_date='2020-11-01' | |
end_date='2020-12-01' | |
def get_linked_accounts(): | |
c = boto3.client('organizations') | |
return(c.list_accounts()) | |
def get_cost(account, start_date, end_date): | |
c = boto3.client('ce') | |
costs = c.get_cost_and_usage( | |
TimePeriod = { | |
'Start': start_date, | |
'End': end_date | |
}, | |
Granularity = 'MONTHLY', | |
Filter = { | |
'Dimensions': { | |
'Key': 'LINKED_ACCOUNT', | |
'Values': [account] | |
} | |
}, | |
Metrics = [ | |
'BlendedCost' | |
], | |
GroupBy = [{ | |
'Type': 'DIMENSION', | |
'Key': 'LINKED_ACCOUNT' | |
}] | |
) | |
return(round(float(costs['ResultsByTime'][0]['Groups'][0]['Metrics']['BlendedCost']['Amount']), 2)) | |
def sort(sub_li): | |
return(sorted(sub_li, key = lambda x: x[1])) | |
def table_style(): | |
return ( | |
('FONT', (0, 0), (-1, -1), 'Helvetica', 12), | |
('TOPPADDING', (3, 3), (-1, -1), 0), | |
('BOTTOMPADDING', (3, 3), (-1, -1), 1), | |
('LEFTPADDING', (3, 3), (-1, -1), 0), | |
('RIGHTPADDING', (3, 3), (-1, -1), 0), | |
('FIRSTLINEINDENT', (3, 3), (-1, -1), 0), | |
('VALIGN', (0, 0), (-1, -1), 'TOP'), | |
('ALIGN', (1, 0), (-1, -1), 'RIGHT') | |
) | |
def generate_pdf(start_date, end_date): | |
f = BytesIO() | |
pdf = PDFDocument(f) | |
table_contents = [] | |
accounts = get_linked_accounts() | |
pdf.init_report() | |
pdf.h1('AWS Billing Per Account for {} through {}'.format(start_date, end_date)) | |
pdf.hr() | |
for account in accounts['Accounts']: | |
table_contents.append([get_cost(account['Id'], start_date, end_date), account['Name']]) | |
pdf.table(sort(table_contents), 2, table_style()) | |
pdf.generate() | |
return f.getvalue() | |
o = open('hello-world.pdf', 'wb') | |
o.write(generate_pdf(start_date, end_date)) | |
o.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Super crude. I also have no idea how that table style is supposed to work. So far, all I can do is mangle the output if I play with the ALIGN and actually make the table readable by changing the paddings to "3, 3".
If I keep working on this I'll find a better PDF library because the one I'm using seems to be abandoned.