Skip to content

Instantly share code, notes, and snippets.

@dgageot
Last active August 29, 2015 13:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dgageot/9429425 to your computer and use it in GitHub Desktop.
Save dgageot/9429425 to your computer and use it in GitHub Desktop.

Google Compute Engine Cost Calculation

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 raw json files

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

Cost computation

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

Machine Type Pricing

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()

Persistent Disk Pricing

There's a monthly cost per Gb used. Source

Disks

  diskCost: (disk) ->
    @daily(disk.sizeGb * 0.04)

Snapshots

  snapshotCost: (snapshot) ->
    @daily(snapshot.diskSizeGb * 0.125)

Monthly cost

It's currently just an approximation.

  monthly: (daily) ->
    daily * (24 * 31) # pessimist

  daily: (monthly) ->
    monthly / (24 * 30) # pessimist

Report

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)

    """

Misc

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]

Feed the CostComputer

new CostComputer
  instances: read 'listinstances'
  disks: read 'listdisks'
  snapshots: read 'listsnapshots'
.print()

TODO

There's still a lot to be done:

  • [x] Machine Type Pricing Source
  • [x] Persistent Disk Pricing Source
  • [ ] Premium Operating Systems Source
  • [ ] Network Pricing Source
  • [ ] Load Balancing and Protocol Forwarding Source
  • [ ] Image Storage Source
  • [ ] IP Address Pricing Source
#!/bin/bash
PROJECT=code-story-blog
mkdir data 2>/dev/null
gcutil --project=$PROJECT listinstances --format=json --zone=europe-west1-a --cache_flag_values > data/listinstances.json
gcutil listdisks > data/listdisks.json
gcutil listsnapshots > data/listsnapshots.json
coffee cost.litcoffee
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment