Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/clean-cost-signals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@cloudburn/rules': minor
'@cloudburn/sdk': minor
cloudburn: minor
---

Remove four heuristic AWS rules that could flag valid cost choices without usage evidence: disabled API Gateway caching, missing CloudWatch metric filters, configured Lambda provisioned concurrency, and ungated S3 Intelligent-Tiering. Default scans no longer report those findings, and the unused provider datasets are no longer loaded or exported.
2 changes: 1 addition & 1 deletion docs/architecture/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Current live-discovery behavior:
- Global tagging discovery is opt-in because it requires an accessible aggregator, and uses one paginated `ListResources` filter query (`resourcetype.supports:tags tag:none`) instead of per-service tagging APIs.
- Missing Lambda `Architectures` values from AWS are normalized to `['x86_64']`, matching the AWS default architecture.
- Lambda hydrators limit in-flight `GetFunctionConfiguration` calls per region to avoid API throttling in large accounts.
- Live scans require Resource Explorer access plus narrow hydrator permissions such as `apigateway:GetStage`, `application-autoscaling:DescribeScalableTargets`, `application-autoscaling:DescribeScalingPolicies`, `ce:GetCostAndUsage`, `cloudfront:GetDistribution`, `cloudfront:ListDistributions`, `cloudtrail:DescribeTrails`, `cloudwatch:GetMetricData`, `dynamodb:DescribeTable`, `ecs:DescribeContainerInstances`, `ecs:DescribeServices`, `ec2:DescribeInstances`, `ec2:DescribeNatGateways`, `ec2:DescribeVolumes`, `eks:ListNodegroups`, `eks:DescribeNodegroup`, `lambda:GetFunctionConfiguration`, `rds:DescribeDBInstances`, `route53:ListHealthChecks`, `route53:ListHostedZones`, `route53:ListResourceRecordSets`, `s3:GetLifecycleConfiguration`, `s3:GetIntelligentTieringConfiguration`, `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:DescribeNotebookInstance`, and `secretsmanager:DescribeSecret`.
- Live scans require Resource Explorer access plus narrow hydrator permissions such as `application-autoscaling:DescribeScalableTargets`, `application-autoscaling:DescribeScalingPolicies`, `ce:GetCostAndUsage`, `cloudfront:GetDistribution`, `cloudfront:ListDistributions`, `cloudtrail:DescribeTrails`, `cloudwatch:GetMetricData`, `dynamodb:DescribeTable`, `ecs:DescribeContainerInstances`, `ecs:DescribeServices`, `ec2:DescribeInstances`, `ec2:DescribeNatGateways`, `ec2:DescribeVolumes`, `eks:ListNodegroups`, `eks:DescribeNodegroup`, `lambda:GetFunctionConfiguration`, `rds:DescribeDBInstances`, `route53:ListHealthChecks`, `route53:ListHostedZones`, `route53:ListResourceRecordSets`, `s3:GetLifecycleConfiguration`, `s3:GetIntelligentTieringConfiguration`, `sagemaker:DescribeEndpoint`, `sagemaker:DescribeEndpointConfig`, `sagemaker:DescribeNotebookInstance`, and `secretsmanager:DescribeSecret`.

## Public Result Shape

Expand Down
4 changes: 0 additions & 4 deletions docs/reference/rule-ids.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,12 @@ meaningful optimization opportunities, and `low` covers hygiene and smaller accu

| ID | Severity | Description | Service | Supports |
| ----------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | -------------- |
| `CLDBRN-AWS-APIGATEWAY-1` | medium | Flags REST API stages when `cacheClusterEnabled` is not explicitly `true`. | apigateway | discovery, iac |
| `CLDBRN-AWS-CLOUDFRONT-1` | medium | Reviews only distributions using `PriceClass_All`. | cloudfront | discovery, iac |
| `CLDBRN-AWS-CLOUDFRONT-2` | medium | Requires a complete 30-day `Requests` history and flags only distributions whose total request count stays below `100`. | cloudfront | discovery |
| `CLDBRN-AWS-CLOUDTRAIL-1` | medium | Flag redundant multi-region CloudTrail trails when more than one trail covers the same account. | cloudtrail | discovery |
| `CLDBRN-AWS-CLOUDTRAIL-2` | medium | Flag redundant single-region CloudTrail trails when more than one trail covers the same region. | cloudtrail | discovery |
| `CLDBRN-AWS-CLOUDWATCH-1` | low | Flag CloudWatch log groups that do not define retention and are not delivery-managed. | cloudwatch | discovery, iac |
| `CLDBRN-AWS-CLOUDWATCH-2` | low | Flags log groups whose most recent observed stream activity is missing or older than 90 days. Delivery-managed log groups remain exempt. | cloudwatch | discovery |
| `CLDBRN-AWS-CLOUDWATCH-3` | low | Reviews only log groups storing at least `1 GiB` and flags them when no metric filters are configured. | cloudwatch | discovery |
| `CLDBRN-AWS-COSTGUARDRAILS-1` | low | Flags accounts whose AWS Budgets summary reports zero configured budgets. | costguardrails | discovery |
| `CLDBRN-AWS-COSTGUARDRAILS-2` | low | Flags accounts whose Cost Anomaly Detection summary reports zero anomaly monitors. | costguardrails | discovery |
| `CLDBRN-AWS-COSTGUARDRAILS-3` | high | Flags configured AWS Budgets only when normalized actual spend is strictly greater than the same-unit budget limit. Malformed and unit-mismatched spend details are skipped. | costguardrails | discovery |
Expand Down Expand Up @@ -114,7 +112,6 @@ meaningful optimization opportunities, and `low` covers hygiene and smaller accu
| `CLDBRN-AWS-S3-2` | medium | Recommend Intelligent-Tiering or another explicit storage-class transition for lifecycle-managed buckets. | s3 | iac, discovery |
| `CLDBRN-AWS-S3-3` | low | Flags buckets when no enabled lifecycle rule aborts incomplete multipart uploads within 7 days. | s3 | iac, discovery |
| `CLDBRN-AWS-S3-4` | medium | Flags only versioned buckets and requires either noncurrent-version expiration or transition cleanup to avoid unbounded version growth. | s3 | iac |
| `CLDBRN-AWS-S3-5` | low | Flags buckets with no lifecycle configuration and no enabled Intelligent-Tiering configuration; lifecycle-managed buckets stay with `CLDBRN-AWS-S3-2`, and an Intelligent-Tiering configuration counts as adoption intent. | s3 | iac, discovery |
| `CLDBRN-AWS-SAGEMAKER-1` | high | Flags only notebook instances whose normalized status remains `InService`. | sagemaker | discovery |
| `CLDBRN-AWS-SAGEMAKER-2` | high | Flags only endpoints whose normalized status remains `InService`, whose parsed `creationTime` is at least `14` days old, and whose complete 14-day `Invocations` total stays at `0`. Endpoints with incomplete metrics are skipped. | sagemaker | discovery |
| `CLDBRN-AWS-SECRETSMANAGER-1` | low | Flags secrets with no `lastAccessedDate` and secrets whose parsed last access is at least `90` days old. | secretsmanager | discovery |
Expand All @@ -123,7 +120,6 @@ meaningful optimization opportunities, and `low` covers hygiene and smaller accu
| `CLDBRN-AWS-LAMBDA-2` | low | Uses 7-day CloudWatch totals and flags only functions whose observed `Errors / Invocations` ratio is greater than `10%`. | lambda | discovery |
| `CLDBRN-AWS-LAMBDA-3` | low | Reviews only functions with configured timeouts of at least `30` seconds and flags when the timeout is at least `5x` the observed 7-day average duration. | lambda | discovery |
| `CLDBRN-AWS-LAMBDA-4` | medium | Reviews only functions configured above `256 MB`, requires invocation history, and flags them when the observed 7-day average duration uses less than `30%` of the configured timeout. | lambda | discovery |
| `CLDBRN-AWS-LAMBDA-5` | high | Flags explicit provisioned concurrency configuration when provisioned concurrent executions are greater than zero. | lambda | iac |

## Presets

Expand Down
11 changes: 5 additions & 6 deletions packages/cloudburn/test/formatters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,10 @@ const resultWithLocation = {
const resultWithSkippedRuleDiagnostic = {
diagnostics: [
{
details:
'Amazon CloudWatch Logs DescribeMetricFilters failed in us-east-1 with ThrottlingException: Rate exceeded.',
message: 'Skipped rule CLDBRN-AWS-CLOUDWATCH-3 because required discovery datasets were unavailable.',
details: 'Amazon CloudWatch Logs DescribeLogStreams failed in us-east-1 with ThrottlingException: Rate exceeded.',
message: 'Skipped rule CLDBRN-AWS-CLOUDWATCH-2 because required discovery datasets were unavailable.',
provider: 'aws' as const,
ruleId: 'CLDBRN-AWS-CLOUDWATCH-3',
ruleId: 'CLDBRN-AWS-CLOUDWATCH-2',
service: 'cloudwatch',
source: 'discovery' as const,
status: 'skipped' as const,
Expand Down Expand Up @@ -149,8 +148,8 @@ describe('renderResponse', () => {

expect(output).toContain('Diagnostics');
expect(output).toContain('Status');
expect(output).toContain('CLDBRN-AWS-CLOUDWATCH-3');
expect(output).toContain('Skipped rule CLDBRN-AWS-CLOUDWATCH-3');
expect(output).toContain('CLDBRN-AWS-CLOUDWATCH-2');
expect(output).toContain('Skipped rule CLDBRN-AWS-CLOUDWATCH-2');
expect(output).not.toContain('ResourceId');
expect(output).not.toContain('AccountId');
});
Expand Down
44 changes: 0 additions & 44 deletions packages/rules/src/aws/apigateway/caching-disabled.ts

This file was deleted.

4 changes: 0 additions & 4 deletions packages/rules/src/aws/apigateway/index.ts

This file was deleted.

7 changes: 1 addition & 6 deletions packages/rules/src/aws/cloudwatch/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { cloudWatchLogGroupNoMetricFiltersRule } from './log-group-no-metric-filters.js';
import { cloudWatchLogGroupRetentionRule } from './log-group-retention.js';
import { cloudWatchUnusedLogStreamsRule } from './unused-log-streams.js';

/** Aggregate AWS CloudWatch rule definitions. */
export const cloudwatchRules = [
cloudWatchLogGroupRetentionRule,
cloudWatchUnusedLogStreamsRule,
cloudWatchLogGroupNoMetricFiltersRule,
];
export const cloudwatchRules = [cloudWatchLogGroupRetentionRule, cloudWatchUnusedLogStreamsRule];
50 changes: 0 additions & 50 deletions packages/rules/src/aws/cloudwatch/log-group-no-metric-filters.ts

This file was deleted.

2 changes: 0 additions & 2 deletions packages/rules/src/aws/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { apigatewayRules } from './apigateway/index.js';
import { cloudfrontRules } from './cloudfront/index.js';
import { cloudtrailRules } from './cloudtrail/index.js';
import { cloudwatchRules } from './cloudwatch/index.js';
Expand All @@ -25,7 +24,6 @@ import { taggingRules } from './tagging/index.js';
// Intent: aggregate all AWS rules into a single provider collection.
// TODO(cloudburn): keep this list synchronized as new AWS rules are added.
export const awsRules = [
...apigatewayRules,
...cloudfrontRules,
Comment thread
axonstone marked this conversation as resolved.
...cloudtrailRules,
...cloudwatchRules,
Expand Down
2 changes: 0 additions & 2 deletions packages/rules/src/aws/lambda/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import { lambdaCostOptimalArchitectureRule } from './cost-optimal-architecture.j
import { lambdaExcessiveTimeoutRule } from './excessive-timeout.js';
import { lambdaHighErrorRateRule } from './high-error-rate.js';
import { lambdaMemoryOverprovisioningRule } from './memory-overprovisioning.js';
import { lambdaProvisionedConcurrencyConfiguredRule } from './provisioned-concurrency-configured.js';

// Intent: aggregate AWS Lambda rule definitions.
export const lambdaRules = [
lambdaCostOptimalArchitectureRule,
lambdaHighErrorRateRule,
lambdaExcessiveTimeoutRule,
lambdaMemoryOverprovisioningRule,
lambdaProvisionedConcurrencyConfiguredRule,
];

This file was deleted.

2 changes: 0 additions & 2 deletions packages/rules/src/aws/s3/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { s3IncompleteMultipartUploadAbortRule } from './incomplete-multipart-upload-abort.js';
import { s3IntelligentTieringRecommendationRule } from './intelligent-tiering-recommendation.js';
import { s3MissingLifecycleConfigRule } from './missing-lifecycle-config.js';
import { s3StorageClassOptimizationRule } from './storage-class-optimization.js';
import { s3VersionedBucketNoncurrentVersionCleanupRule } from './versioned-bucket-noncurrent-version-cleanup.js';
Expand All @@ -10,5 +9,4 @@ export const s3Rules = [
s3StorageClassOptimizationRule,
s3IncompleteMultipartUploadAbortRule,
s3VersionedBucketNoncurrentVersionCleanupRule,
s3IntelligentTieringRecommendationRule,
];
Loading