diff --git a/skills/investigation-cost-guardrail/CHANGELOG.md b/skills/investigation-cost-guardrail/CHANGELOG.md index 436277f..3f74d48 100644 --- a/skills/investigation-cost-guardrail/CHANGELOG.md +++ b/skills/investigation-cost-guardrail/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 2.1.0 + + - Add `references/pricing-reference.md` to resolve the per-region rate for a paid operation at estimation time. + - It ships Price List Query API lookup templates for the operations the skill estimates most often (CloudWatch Logs Insights, `GetMetricData`, Contributor Insights, X-Ray, Athena, S3 requests). + - `SKILL.md` loads it on the first operation Layer 2 classifies as PAID and reuses it for the rest of the investigation; baseline rates are indicative only. + + ## 2.0.0 - Expand the scope from a fixed CloudWatch/X-Ray/CloudTrail set to all AWS service with the agent's own tools; `aws-services` metadata changes to `All`. diff --git a/skills/investigation-cost-guardrail/README.md b/skills/investigation-cost-guardrail/README.md index c34006f..dd1bab5 100644 --- a/skills/investigation-cost-guardrail/README.md +++ b/skills/investigation-cost-guardrail/README.md @@ -110,6 +110,21 @@ Even if AWS launches a new service tomorrow, the heuristic rules will correctly ``` +### Regional Rate Resolution + +Rates vary by AWS Region. `references/pricing-reference.md` lets the skill resolve the rate for the workload's Region rather than applying the us-east-1 baselines listed in Layer 2. + +| Step | What happens | +| --- | --- | +| 1. Region | Derived from the resource ARN | +| 2. Lookup | `pricing:GetProducts`, with the workload Region passed as a `regionCode` filter value | +| 3. Cache | Keyed on `(service, operation, region)` — one lookup per service and Region per investigation | +| 4. Fallback | Published baseline rate, if the lookup is unavailable | + +The reference also maps `usagetype` Region prefixes and their exceptions, S3 Tier1/Tier2 requests, cross-Region transfer rates, and the operations that are free and need no lookup. + +It loads once, on the first operation classified as PAID, and is reused for the rest of the investigation. Investigations that touch only metadata or third-party tools do not load it. Baseline rates are indicative; the live API is authoritative. + ### Layer 3: Response Validation (Self-Learning) After execution, the skill checks response fields for metered indicators: @@ -287,6 +302,28 @@ Add the skill to your Agent Space and adjust the threshold to match your organiz **Option B:** Download the `.zip` directly from the [repository](https://github.com/aws/tools-for-devops-agent/tree/main/skills/investigation-cost-guardrail) and upload it as a skill in your Agent Space. +### Required IAM Permissions + +The skill calls the AWS Price List Query API to resolve per-Region rates. Grant the role your Agent Space assumes: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "pricing:GetProducts", + "Resource": "*" + } + ] +} +``` + +`Resource` is `*` because the Price List API returns public pricing data. The API is free and read-only. + +Your Agent Space tool policy must also permit the call. If the lookup is unavailable, the skill uses the published baseline rates in `references/pricing-reference.md` and flags the estimate. + + ## Known Limitations - **Budget is scoped to a single investigation:** each investigation starts with a fresh budget; cumulative tracking across multiple investigations at the agent space level is not currently supported. diff --git a/skills/investigation-cost-guardrail/SKILL.md b/skills/investigation-cost-guardrail/SKILL.md index 92750d8..60fa362 100644 --- a/skills/investigation-cost-guardrail/SKILL.md +++ b/skills/investigation-cost-guardrail/SKILL.md @@ -3,7 +3,7 @@ name: investigation-cost-guardrail description: Cost guardrail for AWS DevOps Agent that covers ALL AWS services and native agent tools. Before the agent makes any paid API call, this skill estimates cost, enforces budgets per investigation, detects expensive operations across all services (Athena queries, S3 scans, DynamoDB scans, SageMaker inference, PromQL, etc.), enforces time window requirements, monitors cumulative call volume, and cancels if thresholds are exceeded. This skill applies to ALL investigations regardless of which services are involved. metadata: author: tqquresh, inesttia - version: "2.0.0" + version: "2.1.0" aws-devops-agent-skills.agent-types: "Incident RCA" aws-devops-agent-skills.aws-services: "All" aws-devops-agent-skills.technical-domains: "Cost Optimization, Operations" @@ -26,6 +26,9 @@ Rather than listing every free/paid operation across 200+ AWS services, this ski ## Activation This skill MUST be ALWAYS ACTIVE during investigations. It does NOT require user invocation. +## When to Load the Pricing Reference + +`references/pricing-reference.md` holds the authoritative per-region rates and cost formulas. The **first time** an operation is classified **PAID** by Layer 2, you MUST read it **before** estimating that operation's cost. Load it once, then reuse it for the rest of the investigation. Investigations that never invoke a paid AWS operation (metadata-only, or third-party tools only) do not need to load it. --- @@ -133,7 +136,7 @@ If an operation doesn't clearly fit Rules 1–3: ## Layer 2: Known-Paid Registry -These operations have **confirmed pricing** with estimation formulas. This list is extensible — operators can add entries. +These operations have **confirmed pricing** with estimation formulas. This list is extensible — operators can add entries. Per-region rates and usagetype tokens live in the pricing reference. ### Confirmed Paid Operations @@ -316,4 +319,4 @@ When halting or warning, ALWAYS suggest free or cheaper alternatives: | `xray:GetTraceSummaries` (broad) | Narrow time + add filter expression | 90%+ | | `s3:GetObject` (large) | `s3:SelectObjectContent` with SQL | Variable | ---- +--- \ No newline at end of file diff --git a/skills/investigation-cost-guardrail/references/pricing-reference.md b/skills/investigation-cost-guardrail/references/pricing-reference.md new file mode 100644 index 0000000..8663cce --- /dev/null +++ b/skills/investigation-cost-guardrail/references/pricing-reference.md @@ -0,0 +1,93 @@ +# AWS Pricing Reference for Investigation Cost Estimation + +## How to use this file + +1. **Determine workload region** from the resource ARN or `aws_region` param — never default to agent space region. +2. **Query the Pricing API** using the template table below. **Always use `aws_region=us-east-1`** — the Pricing API endpoint only exists in us-east-1 and ap-south-1. Calling it from any other region (ap-northeast-1, sa-east-1, us-west-2, etc.) will fail with a connection error or AccessDeniedException. The workload region appears only as a `regionCode` filter value, never as the API endpoint region. +3. **Cache the result** as `rate_cache[(service, operation, workload_region)]` — one lookup per service+region per investigation. +4. **Fall back to floor rate** only on API failure + +--- + +## Pricing API Query Templates + +All queries follow this structure — always `aws_region=us-east-1`: +```bash +aws pricing get-products --service-code --filters --region us-east-1 +``` + +| Service | ServiceCode | Filter field | Filter value | Floor rate | Formula | +|---|---|---|---|---|---| +| CW Logs Insights | `AmazonCloudWatch` | `usagetype` | `-DataScanned-Bytes` | $0.005/GB ² | `scan_gb × rate` | +| CW GetMetricData | `AmazonCloudWatch` | `operation` | `GetMetricData` | $0.01/1K metrics | `(metrics × periods) / 1K × rate` | +| CW Contributor Insights | `AmazonCloudWatch` | `usagetype` | `-CW:ContributorInsightEvents`| $0.020/1M | `rules × (events / 1M) × rate` | +| X-Ray GetTraceSummaries | `AWSXRay` | `operation` | `XRay-Traces-Scanned` | $0.50/1M traces | `traces / 1M × rate` | +| X-Ray BatchGetTraces | `AWSXRay` | `operation` | `XRay-Traces-Retrieved` | $0.50/1M traces | `traces / 1M × rate` | +| Athena SQL | `AmazonAthena` | `usagetype` | `-DataScannedInTB` | $5.00/TB | `scan_tb × rate`; min 10MB | +| S3 GET/SELECT (Tier2) | `AmazonS3` | `usagetype` | `-Requests-Tier2` | $0.0004/1K | `requests / 1K × rate` | +| S3 PUT/COPY/LIST (Tier1) | `AmazonS3` | `usagetype` | `-Requests-Tier1` | $0.005/1K | `requests / 1K × rate` | + + +--- + +## S3 Tier Mapping + +| Tier | usagetype | Operations | Floor | +|---|---|---|---| +| **Tier1** | `Requests-Tier1` | PUT, COPY, POST, **LIST** | $0.005/1K | +| **Tier2** | `Requests-Tier2` | **GET**, SELECT, HEAD | $0.0004/1K | + +--- + +## Cross-Region Data Transfer Rates + +> ⚠️ **Do NOT use a flat $0.02/GB for all regions.** Transfer rates vary significantly. AP → US is 4.5× higher than EU → US. + +| Source region | Destination | Rate (confirmed via Pricing API) | +|---|---|---| +| us-east-1, us-east-2, us-west-* | Any other AWS region | $0.02/GB | +| eu-* | us-east-1 / other regions | $0.02/GB | +| ap-northeast-1 (Tokyo) | us-east-1 / other regions | $0.09/GB | +| ap-southeast-1 (Singapore) | us-east-1 / other regions | $0.09/GB | +| ap-southeast-2 (Sydney) | us-east-1 / other regions | $0.09/GB | +| ap-south-1 (Mumbai) | us-east-1 / other regions | $0.086/GB | +| sa-east-1 (São Paulo) | us-east-1 / other regions | $0.138/GB | + +**Formula**: `returned_data_gb × regional_transfer_rate` + +--- + +## Region Prefix Mapping + +| Region | Prefix | Exceptions | +|---|---|---| +| us-east-1 | *(none)* | Contributor Insights: always `USE1-`; Lambda: bare `Request`; DynamoDB: bare `ReadRequestUnits` | +| us-east-2 | USE2 | | +| us-west-1 | USW1 | | +| us-west-2 | USW2 | | +| eu-west-1 | EU | X-Ray: `EUW1-` not `EU-` | +| eu-west-2 | EUW2 | | +| eu-west-3 | EUW3 | | +| eu-central-1 | EUC1 | | +| eu-north-1 | EUN1 | | +| ap-southeast-1 | APS1 | | +| ap-southeast-2 | APS2 | | +| ap-northeast-1 | APN1 | | +| ap-northeast-2 | APN2 | | +| ap-south-1 | APS3 | | +| sa-east-1 | SAE1 | | +| ca-central-1 | CAN1 | | +| me-south-1 | MES1 | | +| af-south-1 | AFS1 | | + +--- + +## Free Operations (no cost, no lookup needed) + +`logs:DescribeLogGroups`, `logs:FilterLogEvents`, `cloudtrail:LookupEvents`, `EC2/ECS/RDS Describe*`, `cloudwatch:GetMetricStatistics`, `dynamodb:DescribeTable`, `s3:HeadObject`, `lambda:GetFunction`, `lambda:GetFunctionConfiguration`, `kinesis:DescribeStream`, `kinesis:ListShards`, `kinesis:GetRecords`, `sqs:GetQueueAttributes` + +--- + +## Reference Links + +[CloudWatch](https://aws.amazon.com/cloudwatch/pricing/) · [X-Ray](https://aws.amazon.com/xray/pricing/) · [Athena](https://aws.amazon.com/athena/pricing/) · [DynamoDB](https://aws.amazon.com/dynamodb/pricing/on-demand/) · [S3](https://aws.amazon.com/s3/pricing/) · [Kinesis](https://aws.amazon.com/kinesis/data-streams/pricing/) · [SQS](https://aws.amazon.com/sqs/pricing/) · [Lambda](https://aws.amazon.com/lambda/pricing/) · [Resource Explorer](https://aws.amazon.com/resource-explorer/pricing/) · [Data Transfer](https://aws.amazon.com/ec2/pricing/on-demand/#Data_Transfer)