Cloud Foundry can track billable usage of applications and services. I've been told this but didn't have a reason to look it up until asked about it during our Stark & Wayne training course this week.

UPDATED: previously this post referenced the /v2/billing_events endpoint. It was hidden because it is deprecated (see Dieu Cao's comment). Instead we have two new endpoints.

Application billing

The raw material for data to be sent to your external billing system are the app usage events and service usage events.

$ cf curl /v2/app_usage_events
{
 "resources": [
  {
   "metadata": {
    "url": "/v2/app_usage_events/48497ea7...",
   },
   "entity": {
    "state": "STARTED",
    "memory_in_mb_per_instance": 25,
    "instance_count": 5,
    "app_guid": "06b2bc08...",
    "app_name": "training",
    "space_guid": "e5673264...",
    "space_name": "production",
    "org_guid": "c6f0d863...",
   }
  },
...

Scaling an application's instances (cf scale -i NUM) creates a new app usage event showing the new instance_count.

If a user changes the size of RAM or disk for an application (cf scale -m 128M) then there are 3 events created in quick succession:

  • "state": "STARTED"
  • "state": "STOPPED"
  • "state": "STARTED"

The memory_in_mb_per_instance and instance_count fields are updated in all three event entries.

Changes to the disk are not currently logged in the app usage events. If you need them for billing purposes then you can submit a PR to https://github.com/cloudfoundry/cloud_controller_ng.

Finally, when an application is stopped another app usage event is logged with "state": "STOPPED".

With these raw STARTED and STOPPED usage events your billing integration system would construct billing events and submit them to your billing system:

  • start time, end time
  • duration
  • scale attributes (RAM allocated, instances)
  • organization incurring the chargeable event
  • organization that will pay for the chargable event

Your external billing system will then rate the event (determine how much $), then aggregate the charge events into a bill (perhaps there is a free tier of usage, perhaps a pre-allocated purchase amount, etc).

Services billing

In addition to application billing, you can extrated raw service usage events. Similar to above, you would convert them into events for your billing system.

$ cf curl /v2/service_usage_events
{
 "resources": [
  {
   "metadata": {
    "url": "/v2/service_usage_events/37fba565-dea7-4fdc-9ed5-092a653406e8",
   },
   "entity": {
    "state": "CREATED",
    "org_guid": "c6f0d863...",
    "space_guid": "e5673264...",
    "space_name": "production",
    "service_instance_guid": "50c02a0f...",
    "service_instance_name": "foo",
    "service_instance_type": "managed_service_instance",
    "service_plan_guid": "5fc0b552...",
    "service_plan_name": "free",
    "service_guid": "39cab7d5...",
    "service_label": "postgresql93"
   }
  }
 ]
...

Database maintenance

After you have extracted the raw events above, processed them, and sent them to your billing system you can now clean them out from your Cloud Controller database.

Chris Piraino summarizes how the Cloud Controller automatically cleans out these large tables.

To periodically clean the events table, the cloud_controller_clock has a periodic job that will clean up events older than a specified date. This can be configured with the app_usage_events.cutoff_age_in_days property.

Regardless if your users are external individuals/companies or internal organizations within the same company, you can now regularly extract these start/stop events and pass them into your billing system to generated charges/$ and aggregate into bills/$$$. Lovely.