Skip to content

AWS.CostAndUsageReport reference

Source: src/AWS/CostAndUsageReport/DescribeReportDefinitions.ts

Runtime binding for cur:DescribeReportDefinitions.

Lists the Cost and Usage Report definitions in the account — each entry carries the report’s delivery bucket/prefix, granularity, format, and last delivery status, so a Lambda can discover where its billing data lands before reading the report files from S3. Account-level operation (the API enumerates every definition), so the binding takes no resource argument. Provide the implementation with Effect.provide(AWS.CostAndUsageReport.DescribeReportDefinitionsHttp).

DescribeReportDefinitions: Reading Report Definitions

Section titled “DescribeReportDefinitions: Reading Report Definitions”
// init — account-level binding, no resource argument
const describeReportDefinitions =
yield* AWS.CostAndUsageReport.DescribeReportDefinitions();
// runtime
const { ReportDefinitions } = yield* describeReportDefinitions();
const report = ReportDefinitions?.find((r) => r.ReportName === "costs");
yield* Effect.log(`delivered to s3://${report?.S3Bucket}/${report?.S3Prefix}`);

Source: src/AWS/CostAndUsageReport/ListTagsForResource.ts

Runtime binding for cur:ListTagsForResource — read the tags on the bound ReportDefinition. The report’s name is injected automatically, so the runtime callable takes no arguments.

Provide the implementation with Effect.provide(AWS.CostAndUsageReport.ListTagsForResourceHttp).

// init — grants cur:ListTagsForResource on the report's ARN
const listReportTags =
yield* AWS.CostAndUsageReport.ListTagsForResource(report);
// runtime
const { Tags } = yield* listReportTags();
for (const tag of Tags ?? []) {
yield* Effect.log(`${tag.Key}=${tag.Value}`);
}

Source: src/AWS/CostAndUsageReport/ReportDefinition.ts

An AWS Cost and Usage Report (CUR) definition — the most granular billing data AWS offers, delivered as CSV or Parquet files to an S3 bucket you own.

The CUR API is a global service hosted only in us-east-1; this resource pins every control-plane call there regardless of the stack region. The delivery bucket may live in any region (declared via s3Region) but its bucket policy must grant billingreports.amazonaws.com the s3:GetBucketAcl, s3:GetBucketPolicy, and s3:PutObject permissions — report creation fails validation otherwise.

Report definitions are free; you pay only for the S3 storage of delivered reports.

Daily CSV report with resource IDs

import * as AWS from "alchemy/AWS";
const bucket = yield* AWS.S3.Bucket("ReportBucket", {
bucketName: "my-cur-reports",
policy: [
{
Effect: "Allow",
Principal: { Service: "billingreports.amazonaws.com" },
Action: ["s3:GetBucketAcl", "s3:GetBucketPolicy"],
Resource: "arn:aws:s3:::my-cur-reports",
},
{
Effect: "Allow",
Principal: { Service: "billingreports.amazonaws.com" },
Action: ["s3:PutObject"],
Resource: "arn:aws:s3:::my-cur-reports/*",
},
],
});
const report = yield* AWS.CostAndUsageReport.ReportDefinition("Costs", {
timeUnit: "DAILY",
format: "textORcsv",
compression: "GZIP",
additionalSchemaElements: ["RESOURCES"],
s3Bucket: bucket.bucketName,
s3Prefix: "cur",
s3Region: bucket.region,
});

Athena-ready Parquet report

const report = yield* AWS.CostAndUsageReport.ReportDefinition("Athena", {
timeUnit: "HOURLY",
format: "Parquet",
compression: "Parquet",
additionalArtifacts: ["ATHENA"],
reportVersioning: "OVERWRITE_REPORT",
s3Bucket: bucket.bucketName,
s3Prefix: "athena-cur",
s3Region: bucket.region,
});