This code computes the current hourly and monthly cost of a project on Google Compute Engine. It uses this pricing page as the reference.
Read all the files produced by gcutil
. Then turn each file content into json.
fs = require 'fs'
read = (file) ->
content = fs.readFileSync "data/#{file}.json", {encoding: 'UTF-8'}
JSON.parse(content).items
class CostComputer
constructor: (data) ->
@count = {}
@count[key] = value.length for key,value of data
@cost = 0.0
@cost += @instanceCost(instance) for instance in data.instances
@cost += @diskCost(disk) for disk in data.disks
@cost += @snapshotCost(snapshot) for snapshot in data.snapshots
Each type of none-TERMINATED
instance has a specific hourly cost. Source
instanceCost: (instance) ->
return 0 if instance.status is 'TERMINATED'
switch @type(instance.machineType)
when 'n1-standard-1' then 0.104
when 'n1-standard-2' then 0.207
when 'n1-standard-4' then 0.415
when 'n1-standard-8' then 0.829
when 'n1-standard-16' then 1.659
else throw "Unknown machine type #{instance.machineType}"
type: (machineType) ->
machineType.split('/').last()
There's a monthly cost per Gb used. Source
diskCost: (disk) ->
@daily(disk.sizeGb * 0.04)
snapshotCost: (snapshot) ->
@daily(snapshot.diskSizeGb * 0.125)
It's currently just an approximation.
monthly: (daily) ->
daily * (24 * 31) # pessimist
daily: (monthly) ->
monthly / (24 * 30) # pessimist
Print hourly and monthly cost and the number of moving parts used (instances, disks, snapshots...).
print: -> console.log """
Current cost is:
- $#{@cost} per hour
- $#{@monthly(@cost)} per month
For:
- #{@count.instances} instance(s)
- #{@count.disks} disk(s)
- #{@count.snapshots} snapshot(s)
"""
Extend Array class to be able to get its last value:
Array::last ?= (n) ->
if n? then @[(Math.max @length - n, 0)...] else @[@length - 1]
new CostComputer
instances: read 'listinstances'
disks: read 'listdisks'
snapshots: read 'listsnapshots'
.print()
There's still a lot to be done: