Transact credits from organizations based on usage
In order to charge customers for their usage of Cloud.gov, the service must deduct the appropriate number of credits (or fractions of credits) from customers' accounts periodically.
Each reading and its associated measurements will show a point in time snapshot of brokered service and application usage across the platform. This usage will be in terms of the billable dimension of each kind of resource; for instance, GB of application memory, or number of instances of a brokered service.
On some cadence, the service must transact credits from all organizations based on their usage. This could occur on every usage reading, or on some other frequency, like daily or monthly. Determining the trigger is in scope for this ticket.
Notes:
-
For applications and service instances, they will be billed in a fraction of a credit based on how frequently usage is read. For instance, if it costs 1 credit per day to run a database, and usage is read 10 times per day, each time the database appeared in the usage data, it should cost the customer 0.1 credits. -
For metered services, we may need to write custom code for each service. Two cases to consider: -
S3 storage. AWS bills by the GB-month. How are we charged if a bucket has 1 GB of objects for half the month, and 100 GB for the remainder of the month? Translate this to the credits model. -
SES emails sent. SES is billed per emails sent. Is this tracked by a CloudWatch metric on each identity? If yes, we could compare one reading to the last reading and bill for the difference. Or, we could query the AWS billing APIs monthly, when AWS finalizes the numbers for each month, and deduct credits then.
-
Security considerations
None especially for this item.
Implementation sketch
We should most likely use a double-entry bookkeeping / accounting system to represent customer accounts and usage. A few resources for implementing such a system are here:
- http://markan.net/double-entry.html
- https://web.archive.org/web/20220901165809/https://www.journalize.io/blog/an-elegant-db-schema-for-double-entry-accounting
I suggest creating a Transaction query or function that atomically credits one account and debits another. For instance, credit the "service usage" account and debit the "credits pool" account for a given organization. Then, use that low-level primitive to build queries for starting an IAA PoP, changing a tier partway through, and ending an IAA. Plus others as needed. The basic function may be useful for admins to make one-off changes to customer accounts.