Files
FlociClone/docs/services/ce.md
2026-09-22 08:57:00 -04:00

127 lines
4.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Cost Explorer (`ce:*`)
**Protocol:** JSON 1.1
**Header:** `X-Amz-Target: AWSInsightsIndexService.<Action>`
**Endpoint prefix:** `ce`
Floci synthesizes Cost Explorer responses from its own resource state,
multiplied by the bundled AWS Pricing snapshot served by the
[Pricing service](pricing.md). Costs reflect what's running in Floci right now,
so any test that mutates resources (e.g. creates a bucket, runs an instance)
sees those changes in the next `GetCostAndUsage` call.
## Supported Operations
| Operation | Notes |
|-----------|-------|
| `GetCostAndUsage` | Full `TimePeriod` / `Granularity` / `Filter` / `GroupBy` / `Metrics` support |
| `GetCostAndUsageWithResources` | Same shape as `GetCostAndUsage`; for resource-level breakdown, group by `Type=DIMENSION,Key=RESOURCE_ID` |
| `GetDimensionValues` | Returns dimension values present in the synthesized data set |
| `GetTags` | Returns tag keys / values across enumerated resources |
| `GetReservationCoverage` | Stub — returns zeroed totals; full RI math lands in a follow-up PR |
| `GetReservationUtilization` | Stub — returns zeroed totals |
| `GetSavingsPlansCoverage` | Stub — returns empty list |
| `GetSavingsPlansUtilization` | Stub — returns zeroed totals |
| `GetCostCategories` | Stub — returns empty list (cost-category management not yet emulated) |
## Cost synthesis model
Each Floci service that wants to participate in cost reporting ships a
{@code @ApplicationScoped} bean implementing `ResourceUsageEnumerator`
(in `core/common/`). Cost Explorer auto-discovers these via CDI — adding a new
service with cost data needs zero changes to `CostExplorerService`.
The bundled enumerators cover:
| Service | Priced unit | Source |
|---------|-------------|--------|
| `AmazonEC2` | `BoxUsage:<instanceType>` × hours | `Ec2Service.describeInstances` |
| `AmazonS3` | `TimedStorage-Standard` × GB-month | `S3Service.listBuckets` + `listObjects` |
| `AWSLambda` | `AWS-Lambda-Requests` (zero quantity, catalog only) | `LambdaService.listFunctions` |
| Other Floci services (DDB, SQS, SNS, …) | catalog only, zero quantity | `UnpricedServicesEnumerator` |
Unpriced services emit zero-quantity catalog rows so they remain visible in
`GetDimensionValues SERVICE` responses without contributing billed cost.
## `RECORD_TYPE` semantics
`GROUP_BY=RECORD_TYPE` distinguishes:
| Record type | When emitted |
|-------------|--------------|
| `Usage` | All synthesized usage rows (always present) |
| `Credit` | When `FLOCI_SERVICES_CE_CREDIT_USD_MONTHLY > 0` (see below) |
| `Tax` / `Refund` / `DiscountedUsage` / `SavingsPlan*` | Reserved for future PRs; not currently emitted |
### Synthetic credit injection
Set `FLOCI_SERVICES_CE_CREDIT_USD_MONTHLY` (default `0.0`) to emit a monthly
`Credit` row that offsets `min(creditUsd, monthly Usage cost)`. Useful for
exercising any code path that computes net cost (gross usage − credits) without
having to build credit fixtures by hand.
```yaml
floci:
services:
ce:
credit-usd-monthly: 100.0
```
## Configuration
| Variable | Default | Description |
|---|---|---|
| `FLOCI_SERVICES_CE_ENABLED` | `true` | Enable or disable the service |
| `FLOCI_SERVICES_CE_CREDIT_USD_MONTHLY` | `0.0` | Synthetic monthly credit, applied as a `Credit` `RECORD_TYPE` row |
## Examples
```bash
export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_DEFAULT_REGION=us-east-1
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
aws ce get-cost-and-usage \
--time-period Start=2026-01-01,End=2026-02-01 \
--granularity MONTHLY \
--metrics UnblendedCost \
--group-by Type=DIMENSION,Key=SERVICE
aws ce get-dimension-values \
--time-period Start=2026-01-01,End=2026-02-01 \
--dimension SERVICE
```
```python
import boto3
ce = boto3.client(
"ce",
endpoint_url="http://localhost:4566",
region_name="us-east-1",
)
resp = ce.get_cost_and_usage(
TimePeriod={"Start": "2026-01-01", "End": "2026-02-01"},
Granularity="MONTHLY",
Metrics=["UnblendedCost"],
GroupBy=[{"Type": "DIMENSION", "Key": "SERVICE"}],
Filter={
"Not": {"Dimensions": {"Key": "SERVICE", "Values": ["AmazonRDS"]}}
},
)
for result in resp["ResultsByTime"]:
for group in result["Groups"]:
print(group["Keys"], group["Metrics"]["UnblendedCost"]["Amount"])
```
## Out of Scope
- Forecasting (`GetCostForecast`, `GetUsageForecast`).
- Right-sizing recommendations (`GetRightsizingRecommendation`).
- Anomaly detection management (`GetAnomalies`, `*AnomalyMonitor`, `*AnomalySubscription`) — separate PR planned per #791.
- Real Reservation / Savings Plan utilization math — currently zeroed stubs.
- Cost category management (`CreateCostCategoryDefinition` / `*Definition` / `ListCostCategoryDefinitions`).
- Resource-level granularity beyond what `GetCostAndUsageWithResources` exposes today.