Skip to content

Instantly share code, notes, and snippets.

@gswallow
Created December 12, 2020 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gswallow/0b9d1728948129a6199feccf9849d7f6 to your computer and use it in GitHub Desktop.
Save gswallow/0b9d1728948129a6199feccf9849d7f6 to your computer and use it in GitHub Desktop.
AWS: Generate a monthly-bill-by-account PDF
#!/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()
@gswallow
Copy link
Author

gswallow commented Dec 12, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment