eos-cost-analysis
Skill137 starsChanged 10 days agoApache-2.0View on GitHub
Use this skill whenever a user asks about End of Standard Support (EOS)
In this repository72 other files it gives its agents.
- .claude/CLAUDE.mdCLAUDE.md
- llms.txtllms.txt
- agentcore-observability-setupSkill
- agentcore-ops-reviewSkill
- aiml-access-diagnosticsSkill
- aiml-gpu-training-cluster-investigationSkill
- analytics-opensearch-expertiseSkill
- aws-backup-coverage-reviewSkill
- aws-eks-healthdashboardSkill
- aws-eks-operations-reviewSkill
- aws-fsxn-operations-reviewSkill
- aws-health-eventsSkill
- aws-natgw-traffic-analysisSkill
- aws-routingSkill
- aws-vpc-dns-investigationSkill
- bedrock-adoption-readinessSkill
- bedrock-operation-reviewSkill
- bronto-dataset-discoverySkill
- bronto-error-investigationSkill
- bronto-log-searchSkill
- cloudtrail-cost-optimizationSkill
- config-cost-optimizationSkill
- coralogix-ai-centerSkill
- coralogix-alertsSkill
- coralogix-case-analyticsSkill
- coralogix-case-managementSkill
- coralogix-casesSkill
- coralogix-dashboardsSkill
- coralogix-dataprimeSkill
- coralogix-datasetsSkill
- coralogix-data-usageSkill
- coralogix-docsSkill
- coralogix-infrastructureSkill
- coralogix-logsSkill
- coralogix-metrics-querySkill
- coralogix-ollySkill
- coralogix-rumSkill
- coralogix-service-catalogSkill
- coralogix-single-caseSkill
- coralogix-spansSkill
- coralogix-viewsSkill
- crm-production-investigation-guidelinesSkill
- database-migration-service-expertiseSkill
- database-rds-devopsSkill
- devops-agent-cost-insightsSkill
- ecs-operation-reviewSkill
- eks-upgrade-readinessSkill
- enrich-with-aws-security-agentSkill
- firehose-operation-reviewSkill
- grafana-cloud-investigationSkill
- guardduty-cost-optimizationSkill
- honeycomb-create-boardSkill
- honeycomb-metrics-queriesSkill
- honeycomb-observability-fundamentalsSkill
- honeycomb-production-investigationSkill
- honeycomb-query-patternsSkill
- honeycomb-slos-and-triggersSkill
- honeycomb-verify-recent-traceSkill
- investigation-cost-guardrailSkill
- live-streaming-event-readiness-reviewSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
28 rules. About 0 are common, 22 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈22
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 80
NEVER guess or estimate EOS dates — always verify from AWS documentation, per exact engine + version
- Distinctive: line 81
NEVER reuse one version's EOS date for another version, even within the same service — verify each version independently
- Distinctive: line 82
NEVER fabricate pricing rates — retrieve live rates from the AWS Pricing API (Step 3.2)
- Very specific: line 83
When calling the Pricing API, ALWAYS extract only pricePerUnit — never dump the full PriceList (responses are very large)
- Very specific: line 84
If a version's EOS date is not found, mark it UNVERIFIED and set the dependent fields as in references/billing-rules.md, section 6
- Distinctive: line 85
All output is AI-generated and must be independently verified before taking action
- Distinctive: line 86
Read-only operations only — do not modify any resources
- Distinctive: line 93
If user specifies a service (e.g., "EKS EOS") → analyze that service only
- Distinctive: line 94
If user says "all services" or "full EOS analysis" → analyze all 5 supported services
- Distinctive: line 95
If unclear, ask: "Which service would you like me to analyze?
- Distinctive: line 101
If user says "only this account" or specifies an account ID → limit to that account
- Distinctive: line 104
If user specifies regions → use those
- Distinctive: line 111
Large-scope warning: if the scope is large (e.g., >10 accounts, or all services × all regions × many accounts), add a heads-up that this …
- Distinctive: line 112
Default behavior: all services, all associated accounts, all regions — proceed WITHOUT asking, unless the user narrows it.
- Very specific: line 120
PAGINATION (MANDATORY): All discovery APIs paginate.
- Very specific: line 164
Look up the vCPU count for each instance class using documentation search (verify_aws_claim) or the AWS Pricing API product attributes
- Distinctive: line 166
If an instance class is not in this list, verify its vCPU count rather than guessing
- Distinctive: line 215
After discovery completes, present a summary that makes COVERAGE provable — a reader must be able to confirm every discovery path actually …
- Distinctive: line 233
Search AWS documentation for the EXACT engine + version combination discovered (e.g., the specific engine family AND version number as …
- Distinctive: line 234
Search AWS documentation: "[service] version lifecycle" / "[service] supported versions calendar"
- Distinctive: line 238
Verify the EOS date for EACH distinct version SEPARATELY.
- Distinctive: line 241
If two versions appear to have the same EOS date, double-check — identical dates across clearly different versions/engines is a red flag …
- Distinctive: line 247
If documentation search returns no result for a specific version:
- Distinctive: line 250
Do NOT substitute a similar version's date as a proxy
- Very specific: line 325
Use verify_aws_claim (or AWS documentation search): "[service] upgrade from [version] to latest"
- Very specific: line 354
Every cost uses one formula (references/billing-rules.md, section 1): monthly_cost = billed_units_per_hour × es_rate × 730.
- Distinctive: line 372
Every affected resource has TWO cost figures.
- Distinctive: line 480
If deprecated Lambda runtimes were found:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
EOS Cost Analysis
Discover AWS resources approaching End of Standard Support, calculate Extended Support charges, and generate an actionable cost-impact report.
When to Use This Skill
- User asks about End of Support cost exposure, Extended Support charges, or version-deprecation cost
- User wants to know which resources are incurring or will incur Extended Support charges
- User wants an EOS cost or inventory report / posture assessment across accounts
- User wants a cost-impact report for deprecated service versions
- Proactive scheduled checks for EOS posture across the organization
This skill scopes the EOS cost and inventory picture. It is not an upgrade-execution skill — for EKS pre-upgrade readiness and upgrade planning, use eks-upgrade-readiness; for OpenSearch domain health beyond version lifecycle, use analytics-opensearch-expertise.
Supported Services (Phase 1 — Extended Support Charges)
| Service | Billing Unit | Discovery API |
| Amazon EKS | Per cluster/hour | eks:ListClusters, eks:DescribeCluster |
| Amazon RDS/Aurora | Per vCPU/hour per billed instance; per ACU-hour for Aurora Serverless v2 | rds:DescribeDBInstances, rds:DescribeDBClusters |
| AWS Lambda | No direct ES charge (security risk only) | lambda:ListFunctions |
| Amazon ElastiCache | Per node/hour (Redis OSS v4–v6 only) | elasticache:DescribeCacheClusters, elasticache:DescribeReplicationGroups, elasticache:DescribeServerlessCaches |
| Amazon OpenSearch | Per Normalized Instance Hour, or equal to instance cost during an extension period | opensearch:ListDomainNames, opensearch:DescribeDomain |
Which resources are billed, in what unit and how many units are defined in references/billing-rules.md. Follow it for every classification and cost.
IAM prefix note: the
use_awscalls above useopensearchbecause that is the correct API client name, but the corresponding IAM actions live under thees:prefix (es:ListDomainNames,es:DescribeDomain,es:DescribeDomains). TheAIDevOpsAgentAccessPolicymanaged policy already grants the discovery actions for all five services.
Extended Support Pricing
Pricing is ALWAYS retrieved live from the AWS Pricing API (pricing:GetProducts) — see Phase 3, Step 3.2. The API is the single source of truth; the rates below are a validation reference only (sanity-check the API result against them; never substitute them for the API value).
Validation reference rates (us-east-1)
| Service | Year 1-2 rate | Year 3 rate | Billing unit | Tier behavior |
| EKS | $0.50/cluster/hour | $0.50/cluster/hour | per cluster/hour | Flat — no Year 3 escalation. This is the ES premium on top of the $0.10 standard cluster cost. |
| RDS | $0.10/vCPU/hour | $0.20/vCPU/hour | per vCPU/hour | Year 3 = 2× Year 1-2 |
| Aurora Serverless v2 | $0.085/ACU-hour for Aurora PostgreSQL 13 | — | per ACU-hour | Read the Yr3 usagetype when it applies |
| ElastiCache | $0.165/node/hour for cache.r6g.large (rate depends on node type, e.g. $0.054 for cache.t3.medium) | $0.330/node/hour for cache.r6g.large | per node/hour | Year 3 = 2× Year 1-2 |
| OpenSearch | $0.0065/NIH (m7g.medium.search = 2 NIH per hour); during an extension period, the instance's own hourly price (m7g.medium.search $0.068) | — | per NIH or per instance-hour | No Year 3 escalation |
| Lambda | — | — | — | No Extended Support charge (deprecated runtimes are a security risk only) |
After Year 3, AWS may force-upgrade the resource. Cost framing: these rates represent the AVOIDABLE Extended Support premium (what the customer eliminates by upgrading). For EKS, the $0.50/hour is the ES surcharge on top of the $0.10 standard cluster cost the customer pays regardless — report the premium as the cost exposure/savings opportunity, not the standard cost.
Prerequisites
- Discovery APIs (listed per service above) and the CloudWatch metric reads for Aurora Serverless v2 usage are covered by the
AIDevOpsAgentAccessPolicymanaged policy - The Pricing API actions
pricing:GetProducts,pricing:GetAttributeValuesandpricing:DescribeServicesfor live Extended Support pricing, granted by theEnableEosCostAnalysisparameter of the skill-policies CloudFormation template - For organization-wide analysis: resources across all associated accounts (via Agent Space cloud source associations)
- For EOS date validation and upgrade guidance:
verify_aws_claimor AWS documentation search
Constraints
- NEVER guess or estimate EOS dates — always verify from AWS documentation, per exact engine + version
- NEVER reuse one version's EOS date for another version, even within the same service — verify each version independently
- NEVER fabricate pricing rates — retrieve live rates from the AWS Pricing API (Step 3.2)
- When calling the Pricing API, ALWAYS extract only
pricePerUnit— never dump the full PriceList (responses are very large) - If a version's EOS date is not found, mark it
UNVERIFIEDand set the dependent fields as in references/billing-rules.md, section 6 - All output is AI-generated and must be independently verified before taking action
- Read-only operations only — do not modify any resources
Phase 1: Scope Definition
- Identify target service(s) from the user request:
- If user specifies a service (e.g., "EKS EOS") → analyze that service only
- If user says "all services" or "full EOS analysis" → analyze all 5 supported services
- If unclear, ask: "Which service would you like me to analyze? (EKS, RDS, Lambda, ElastiCache, OpenSearch, or all)"
- Determine account scope:
- Default: ALL associated accounts — Scan resources in ALL AWS accounts connected to this Agent Space (primary + all secondary cloud sources)
- The agent has access to multiple accounts through its cloud source associations — discover resources in EACH account, not just the primary
- To identify available accounts: attempt resource discovery in all accounts the agent has access to. The Agent Space configuration determines which accounts are available.
- If user says "only this account" or specifies an account ID → limit to that account
- Determine region scope:
- If user specifies regions → use those
- Otherwise → scan all commercially available regions
- Optimization: first check which regions have resources for the target service using a quick
Listcall in each region
- State scope and estimate scan size, then proceed (do NOT block on a prompt):
- Announce: "Analyzing [service(s)] across [N accounts] in [regions]."
- Estimate scan size before starting: roughly
services × accounts × regionsList calls (plus per-resource Describe calls). Report the rough magnitude so the user knows what to expect. - Large-scope warning: if the scope is large (e.g., >10 accounts, or all services × all regions × many accounts), add a heads-up that this may take a while and involve hundreds of API calls — but still proceed automatically.
- Default behavior: all services, all associated accounts, all regions — proceed WITHOUT asking, unless the user narrows it. Only the scope announcement and size estimate are required; no confirmation gate.
Phase 2: Resource Discovery
For each account and region in scope, call the appropriate service APIs.
PAGINATION (MANDATORY): All discovery APIs paginate. You MUST follow pagination tokens to retrieve ALL resources — never rely on the first page. Continue calling with the NextToken / Marker / nextToken until no token is returned:
lambda:ListFunctions→NextMarker(default page size 50)rds:DescribeDBInstances/rds:DescribeDBClusters→Markereks:ListClusters→nextTokenelasticache:DescribeCacheClusters→Markerelasticache:DescribeReplicationGroups→Markerelasticache:DescribeServerlessCaches→NextTokenopensearch:ListDomainNames→ returns all in one call (no pagination)
Under-counting due to skipped pages is a correctness failure. Always exhaust pagination.
EKS Discovery
use_aws: eks:ListClusters (region: <region>)
→ For each cluster name:
use_aws: eks:DescribeCluster (name: <cluster_name>, region: <region>)
→ Extract: clusterName, version, arn, createdAtRecord: account_id, region, cluster_name, cluster_arn, kubernetes_version
RDS Discovery
RDS Extended Support applies to both standalone RDS instances AND Aurora clusters. Query BOTH APIs — Aurora version/engine data comes from the cluster API, not the instance API.
use_aws: rds:DescribeDBInstances (region: <region>) # standalone RDS + Aurora member instances
→ For each instance:
→ Extract: DBInstanceIdentifier, Engine, EngineVersion, DBInstanceClass,
MultiAZ, DBInstanceArn, DBClusterIdentifier,
ReadReplicaSourceDBInstanceIdentifier
use_aws: rds:DescribeDBClusters (region: <region>) # Aurora clusters (authoritative engine version)
→ For each cluster:
→ Extract: DBClusterIdentifier, Engine, EngineVersion, DBClusterArn,
DBClusterMembers (instance identifiers)Filter: In scope are the engines and major versions on the RDS and Aurora Extended Support pages (references/billing-rules.md, section 2): today mysql, postgres, aurora-mysql and aurora-postgresql. Other engines (mariadb, oracle-*, sqlserver-*) have no Extended Support charge or Pricing API usagetype, so list them in the discovery summary as out of scope and do not price them.
Billed instances: Count every instance on an affected version (primary, standbys, readable standbys, read replicas) by deployment shape, per references/billing-rules.md, section 3. A Multi-AZ DB instance adds one unlisted standby; cluster members, Aurora included, are listed individually and are never doubled. For Aurora, use the cluster's EngineVersion as the authoritative version (instance-level version may lag). A db.serverless instance is priced in ACU-hours (section 5), not vCPUs.
Record: account_id, region, resource_id, engine, engine_version, instance_class, multi_az, cluster_id, read_replica_source, billed_instances, arn
Instance class to vCPU mapping (required for cost calculation):
- Look up the vCPU count for each instance class using documentation search (
verify_aws_claim) or the AWS Pricing API product attributes - Common mappings: db.t3.micro=2, db.t3.small=2, db.t3.medium=2, db.r5.large=2, db.r5.xlarge=4, db.r5.2xlarge=8, db.r5.4xlarge=16, db.r6g.large=2, db.r6g.xlarge=4, db.r6g.2xlarge=8
- If an instance class is not in this list, verify its vCPU count rather than guessing
Lambda Discovery
use_aws: lambda:ListFunctions (region: <region>)
→ For each function:
→ Extract: FunctionName, Runtime, FunctionArn, LastModifiedFilter: Include functions whose runtime is deprecated or approaching deprecation.
Do NOT pattern-match against a hardcoded runtime list — deprecated runtimes change frequently. Instead, collect the DISTINCT set of runtimes in use, then verify each one's deprecation status at runtime via documentation search (verify_aws_claim: "AWS Lambda [runtime] deprecation date" / "AWS Lambda runtime deprecation schedule"). Flag any runtime that is past its deprecation date or has a deprecation date within 6 months.
Record: account_id, region, function_name, runtime, arn, last_modified
ElastiCache Discovery
use_aws: elasticache:DescribeCacheClusters (region: <region>, ShowCacheNodeInfo: true)
→ For each cluster:
→ Extract: CacheClusterId, Engine, EngineVersion, CacheNodeType, NumCacheNodes, ARN
use_aws: elasticache:DescribeReplicationGroups (region: <region>) # for clustered/replicated deployments
→ Extract group-level engine version where applicable
use_aws: elasticache:DescribeServerlessCaches (region: <region>) # ElastiCache Serverless — SEPARATE resource type
→ For each serverless cache:
→ Extract: ServerlessCacheName, Engine, MajorEngineVersion, FullEngineVersion, ARNServerless caches are a distinct resource type — they are NOT returned by DescribeCacheClusters. You MUST call DescribeServerlessCaches separately so every cache is accounted for. Serverless uses MajorEngineVersion / FullEngineVersion (there is no node type / node count), and the Pricing API has no Extended Support usagetype for serverless caches, so never price one as nodes (references/billing-rules.md, section 2).
Filter: Discover all engines, but only Redis OSS v4, v5 and v6 have Extended Support (references/billing-rules.md, section 2). Valkey and Memcached are out of scope: list them in the discovery summary as supported, with no charge.
Record (node-based): account_id, region, cluster_id, engine, engine_version, node_type, num_nodes, arn
Record (serverless): account_id, region, serverless_cache_name, engine, engine_version, is_serverless=true, arn
OpenSearch Discovery
use_aws: opensearch:ListDomainNames (region: <region>)
→ For each domain name:
use_aws: opensearch:DescribeDomain (DomainName: <name>, region: <region>)
→ Extract: DomainName, EngineVersion, ARN, and every node group in ClusterConfig:
InstanceType/InstanceCount, DedicatedMasterType/Count, WarmType/CountEngine family split (date-bleed risk): EngineVersion comes back prefixed as either OpenSearch_2.x or Elasticsearch_7.x. These are TWO different engine families with COMPLETELY different EOS calendars — an OpenSearch version's EOS date must never be applied to an Elasticsearch version, or vice versa. Parse the prefix, treat Elasticsearch_* and OpenSearch_* as separate engines during EOS validation (Phase 3), and verify each independently. The Pricing API usagetype may also differ between the two families — resolve it per family, don't assume one covers both.
Record: account_id, region, domain_name, engine_family (OpenSearch|Elasticsearch), engine_version, node groups (type and count each), arn
Discovery Summary
After discovery completes, present a summary that makes COVERAGE provable — a reader must be able to confirm every discovery path actually ran, even when it found nothing chargeable:
- APIs called per service — explicitly confirm which discovery APIs were invoked, especially the ones that are easy to skip:
elasticache:DescribeServerlessCaches,elasticache:DescribeReplicationGroups,rds:DescribeDBClusters. If an API was not called for a region, say so. - Total resources found per service (count of ALL discovered, not just affected).
- Every discovered resource must be accounted for, including SUPPORTED ones. Do NOT silently drop supported resources — list them (at minimum a per-service, per-engine count of SUPPORTED resources) so the reader can tell "scanned and supported" apart from "never scanned". A bare "12 supported" with no breakdown is not acceptable.
- Unique versions detected (with counts) and their classification.
- Accounts and regions with resources.
This visibility is what lets a reviewer distinguish a genuine clean result (e.g., serverless caches found but on supported engines) from a coverage gap (serverless never queried). The final report (Phase 5) MUST carry this through: include a "Discovered but SUPPORTED (no charge)" section listing those resources or per-engine counts.
Phase 3: EOS Classification and Pricing Validation
Step 3.1 — Validate EOS Dates
For each unique version discovered, verify its End of Standard Support date independently:
- Search AWS documentation for the EXACT engine + version combination discovered (e.g., the specific engine family AND version number as reported by the discovery API — do not generalize).
- Search AWS documentation: "[service] version lifecycle" / "[service] supported versions calendar"
- Extract:
eos_date(end of standard support),es_end_date(end of extended support)
CRITICAL — Per-version verification (avoid date bleed):
- Verify the EOS date for EACH distinct version SEPARATELY. Never reuse one version's date for another version, even within the same service.
- Many AWS services have MULTIPLE engine families or generations with completely different lifecycles (for example, a service may have a legacy engine line and a newer engine line that share a console but have separate support calendars). Treat each engine family + version as its own lookup.
- Match the EOS date to the EXACT version string returned by discovery. If discovery returns an engine name and a version number, both must match the documentation entry you cite.
- If two versions appear to have the same EOS date, double-check — identical dates across clearly different versions/engines is a red flag that a date was incorrectly copied.
Sanity checks before accepting an EOS date:
- Does the date make chronological sense given the version's release date? (Older versions should have earlier EOS dates than newer ones of the same engine.)
- Is a version that is clearly several generations behind the current release being reported as "supported with a future EOS date"? If so, re-verify — it may already be past EOS.
If documentation search returns no result for a specific version:
- Mark as
UNVERIFIEDand set the dependent fields per references/billing-rules.md, section 6 - Note in the report: "EOS date could not be confirmed from AWS documentation — verify manually"
- Do NOT substitute a similar version's date as a proxy
Step 3.2 — Get Extended Support Pricing (AWS Pricing API)
Use the AWS Pricing API (pricing:GetProducts) for authoritative, real-time Extended Support pricing. Do NOT use documentation search or model knowledge for pricing.
CRITICAL — Response size: The Pricing API returns large JSON. ALWAYS use the exact usagetype patterns below and extract ONLY pricePerUnit. Never dump the full PriceList into context.
Pricing API constraints:
- Region: call the Pricing API in
us-east-1(its endpoint region) - Requires
pricing:GetProductsandpricing:GetAttributeValues(pluspricing:DescribeServicesfor the empty-result fallback below) - The
regionCodefilter targets the region you're pricing for (e.g.,us-east-1), separate from the API endpoint region
Per-service pricing lookup:
| Service | ServiceCode | Usage Type Pattern | Region Prefix | Billing Unit | Year 3 |
| EKS | AmazonEKS | {PREFIX}-AmazonEKS-Hours:extendedSupport | Yes, in every region (USE1- in us-east-1) | per cluster/hour | Flat (no escalation) |
| RDS | AmazonRDS | {PREFIX}-ExtendedSupport:Yr1-Yr2:{EngineVersion} / {PREFIX}-ExtendedSupport:Yr3:{EngineVersion}; Aurora Serverless v2 adds ASv2 (references/billing-rules.md, section 5) | None in us-east-1, prefixed elsewhere (USW2-, EU-, APS3-...) | per vCPU/hour; per ACU-hour for ASv2 | 2× Yr1-2 |
| ElastiCache | AmazonElastiCache | {PREFIX}-ExtendedSupportYr1_Yr2-NodeUsage:{nodeType} / {PREFIX}-ExtendedSupportYr3-NodeUsage:{nodeType} | Yes, in every region (USE1- in us-east-1) | per node/hour | 2× Yr1-2 |
| OpenSearch | AmazonES | {PREFIX}-OpenSearchExtendedSupport (NIH mode); {PREFIX}-ESInstance:{type} (extension-period mode, references/billing-rules.md, section 4) | None in us-east-1, prefixed elsewhere (EU-, APS3-...) | per NIH/hour or per instance-hour | Single tier (no escalation) |
| Lambda | — | No Extended Support charge | — | — | — |
Whether us-east-1 carries a prefix depends on the service, so never assume. Checked against the live Pricing API:
- RDS and OpenSearch have NO prefix in us-east-1 (
ExtendedSupport:Yr1-Yr2:MySQL8.0,OpenSearchExtendedSupport) and a prefix in every other region (APS3-ExtendedSupport:Yr1-Yr2:MySQL8.0,EU-OpenSearchExtendedSupport). Outside us-east-1 the bare form returns 0 products, which would silently turn the resource intoPRICING_UNAVAILABLEor $0. - EKS and ElastiCache carry a prefix everywhere,
USE1-in us-east-1. - RDS
{EngineVersion}is the engine plus its major version, not the bare engine:MySQL8.0,MySQL5.7,PostgreSQL13,AuroraMySQL2,AuroraMySQL3,AuroraPostgreSQL13. Build it from the discoveredEngineand majorEngineVersion, and confirm it withpricing:GetAttributeValues. If no usagetype exists for that engine and version, mark the costPRICING_UNAVAILABLEinstead of guessing.
Region prefix mapping (EKS, RDS, ElastiCache, OpenSearch):
The AUTHORITATIVE way to get the region prefix is the Pricing API — do NOT rely on a hardcoded prefix for any region you are not certain about. For ANY region outside the common set below, call pricing:GetAttributeValues on the usagetype attribute (filtered by ServiceCode) and match the prefix for your target regionCode. This is the DEFAULT method, not a fallback, and it applies to every service.
Common prefixes (safe to use directly; still verify via API if a lookup returns empty). These apply to every service except where the list above says there is no prefix in us-east-1:
- us-east-1 →
USE1| us-east-2 →USE2| us-west-1 →USW1| us-west-2 →USW2 - eu-west-1 →
EU(notEUW1, which returns nothing) | eu-west-2 →EUW2| eu-central-1 →EUC1 - ap-northeast-1 →
APN1| ap-southeast-1 →APS1| ap-southeast-2 →APS2 - ca-central-1 →
CAN1| sa-east-1 →SAE1
Regions you MUST resolve via the API (prefixes vary / are not reliably guessable — includes ap-south-1, eu-north-1, eu-south-1, me-south-1, af-south-1, ap-east-1, and any region not listed above): call pricing:GetAttributeValues and read the actual usagetype prefix rather than guessing. Never construct a usagetype from an unverified prefix — a wrong prefix silently returns empty and causes a resource to be under-costed as $0.
Lookup procedure per affected resource:
- Build the usagetype string using the pattern + region prefix + resource attribute (engine version / node type as applicable). Take the prefix from the rules above: none for RDS and OpenSearch in us-east-1,
USE1-for EKS and ElastiCache in us-east-1, and for any other region resolve it viapricing:GetAttributeValues(do not guess). For exampleExtendedSupport:Yr1-Yr2:AuroraMySQL2in us-east-1 butUSW2-ExtendedSupport:Yr1-Yr2:AuroraMySQL2in us-west-2. - Call
pricing:GetProducts:
Apply ause_aws: pricing:GetProducts ( region: "us-east-1", ServiceCode: "<ServiceCode>", Filters: [ {Type: "TERM_MATCH", Field: "usagetype", Value: "<constructed usagetype>"}, {Type: "TERM_MATCH", Field: "regionCode", Value: "<target region>"} ] )jmespath_filterat the API call to return ONLY the price, so the large PriceList JSON never enters context. Pricing API returns each product as a JSON-encoded string inPriceList; filter/parse down to thepricePerUnit.USDvalue inside the on-demand price dimensions rather than pulling the whole payload. Filtering at the call level is more reliable than asking the model to extract it afterward. - Extract ONLY
pricePerUnit.USDand the price dimension'sunit(for examplevCPU-hour,ACU-hour,Hrs) — ignore everything else. The unit decides what you count in Phase 4 (references/billing-rules.md, section 1) - If the exact usagetype returns empty, call
pricing:GetAttributeValuesfor theusagetypeattribute to discover the correct format, then retry. If it is still empty, usepricing:DescribeServicesto confirm theServiceCodeand the exact attribute names for that service before constructing anotherGetAttributeValues/GetProductscall — a wrong ServiceCode or attribute name also returns empty.
Validate the returned rate against the reference table in the Extended Support Pricing section (us-east-1 validation reference). The API result is authoritative — the table is only a sanity check. If the API rate is wildly different from the reference (orders of magnitude), re-check the usagetype before trusting it; never replace the API result with the reference number.
Step 3.3 — Classify Each Resource
Compare each resource's version against the validated EOS dates:
| Status | Condition | Include in Report? |
IN_EXTENDED_SUPPORT | EOS date is past, ES end date is future | YES — currently incurring charges |
APPROACHING_EOS | EOS date is within 6 months from today | YES — will soon incur charges |
PAST_EXTENDED_SUPPORT | Both EOS and ES end dates are past | YES — critical, may be force-upgraded |
SUPPORTED | EOS date is more than 6 months away, or the engine is out of scope | NO — exclude from cost report (list in the discovery summary) |
UNVERIFIED | No EOS date confirmed for the exact engine and version | YES — listed separately, kept out of the totals |
Step 3.4 — Search Upgrade Recommendations
For each affected version:
- Use
verify_aws_claim(or AWS documentation search): "[service] upgrade from [version] to latest" - Extract: recommended target version, key breaking changes, migration guide URL
Phase 4: Cost Calculation
Step 4.1 — Determine pricing tier
Extended Support pricing tiers are based on how long a resource has been past End of Standard Support. The tier structure differs by service:
- Calculate months since EOS:
months_since_eos = (today - eos_date).months - Year 1-2 —
months_since_eos < 24(months 0–23 past EOS): base rate - Year 3 —
months_since_eos >= 24(month 24 onward past EOS): elevated rate
Boundary is exclusive at 24: month 23 is still Year 1-2, month 24 is the first Year 3 month. No month falls in both tiers.
Tier behavior by service (rates themselves come from the Pricing API; see the validation reference table):
- EKS: flat — no Year 3 escalation
- RDS: Year 3 = 2× Year 1-2
- ElastiCache: Year 3 = 2× Year 1-2 (per node, varies by node type)
- OpenSearch: single tier — no escalation
Use the exact rate returned by the Pricing API for the resource's tier (Step 3.2). Query the Yr3 usagetype pattern for resources 24+ months past EOS.
When the Year 3 usagetype is not yet published: for a resource whose Year 3 window starts in the future (e.g. it is currently in Year 1-2 but will cross 24 months later), the Yr3 usagetype may not exist in the Pricing API yet and will return empty. This is expected, not a lookup failure — do NOT mark it PRICING_UNAVAILABLE. Use the current Year 1-2 rate for the current cost, and for the Year 3 projection derive it from the service's documented escalation (RDS and ElastiCache: 2× the Year 1-2 rate; EKS and OpenSearch: no escalation, so Year 3 = Year 1-2). Clearly label such a projected Year 3 figure as derived (not API-returned) and note the date the Year 3 rate begins.
Step 4.2 — Calculate per-resource monthly cost
Every cost uses one formula (references/billing-rules.md, section 1): monthly_cost = billed_units_per_hour × es_rate × 730. es_rate is the per-tier rate the Pricing API returned for the resource (Step 3.2), never a hardcoded value, and billed_units_per_hour is counted in that rate's unit:
| Service | billed_units_per_hour |
| EKS | 1 per cluster |
| RDS / Aurora provisioned | vCPUs of the instance class × billed instances (section 3): one standby added for a Multi-AZ DB instance, read replicas counted, cluster members (Aurora included) each counted once and never doubled |
| Aurora Serverless v2 | Average ACUs consumed (CloudWatch ServerlessDatabaseCapacity, section 5), else USAGE_DEPENDENT |
| ElastiCache | Nodes on Redis OSS v4–v6 |
| OpenSearch | NIH mode: Σ node groups of instance_count × normalization factor from the section 4 table (medium = 2, large = 4, xlarge = 8, …). Extension-period mode: instances, at the instance type's own hourly rate |
| Lambda | 0 (flag as security risk only) |
Notes:
- The EKS ES rate is the Extended Support premium (the avoidable cost). The standard cluster cost applies regardless and is NOT part of the exposure.
- For RDS, map instance class to vCPU count (e.g., db.r6g.xlarge = 4 vCPUs).
- For OpenSearch, take the charge mode for the version and date from section 4, and never derive a normalization factor from instance count or by extrapolation.
Step 4.2b — Reactive (current) vs Proactive (projected) cost
Every affected resource has TWO cost figures. Compute both so the report shows what the customer pays now AND what they will pay if they do nothing:
- Current monthly ES cost (reactive) — what the resource is incurring RIGHT NOW.
IN_EXTENDED_SUPPORT/PAST_EXTENDED_SUPPORT: the Year 1-2 or Year 3 rate from Step 4.2. This is real spend today.APPROACHING_EOS: $0 — not yet in Extended Support, incurring nothing today.
- Projected monthly ES cost (proactive) — what the resource WILL cost once it enters Extended Support, if not upgraded first.
APPROACHING_EOS: compute the full Year 1-2 ES cost using the SAME per-resource formula (Step 4.2), as if it were already in ES. This is the cost that starts on its EOS date (within the next 6 months).IN_EXTENDED_SUPPORT/PAST_EXTENDED_SUPPORT: projected = current (already incurring). If the resource will cross into Year 3 (>= 24months) within the projection window, project the Year 3 (elevated) rate and note the escalation.UNVERIFIED,PRICING_UNAVAILABLEandUSAGE_DEPENDENTresources: set the fields per references/billing-rules.md, section 6; keep them out of the totals and count them separately.
This split is the whole point of the skill: reactive = stop the bleeding on resources already in ES; proactive = show the cost cliff approaching in the next 6 months so the customer can upgrade before it hits. Report both, never collapse them into one number.
Step 4.3 — Assign urgency
| Urgency | Condition |
CRITICAL | IN_EXTENDED_SUPPORT or PAST_EXTENDED_SUPPORT (already incurring charges) |
HIGH | APPROACHING_EOS within 3 months |
MEDIUM | APPROACHING_EOS within 3–6 months |
UNVERIFIED | UNVERIFIED status (no confirmed EOS date): verify manually |
Step 4.4 — Aggregate totals
Calculate:
- Total current monthly ES cost (reactive) — sum of current cost across resources already in/past ES (excludes APPROACHING_EOS, which is $0 now)
- Total current annual ES cost (current monthly × 12)
- Total projected monthly ES cost (proactive) — sum of projected cost across ALL affected resources (includes APPROACHING_EOS at their future ES rate). This is the monthly run-rate if nothing is upgraded in the next 6 months.
- Incremental cost cliff — projected monthly − current monthly = the additional spend that switches on as APPROACHING_EOS resources cross their EOS dates
- Top 10 most impacted accounts (by projected monthly cost)
- Cost by service breakdown (current and projected)
- Cost by urgency breakdown
- Not in totals: counts of
UNVERIFIED,PRICING_UNAVAILABLEandUSAGE_DEPENDENTresources, each listed
Phase 5: Report Generation
Step 5.1 — Present Summary
## EOS Cost Impact Summary
| Metric | Value |
|--------|-------|
| Current Monthly ES Cost (incurring now) | $X,XXX |
| Current Annual ES Cost | $XX,XXX |
| Projected Monthly ES Cost (if no upgrades in next 6 mo) | $X,XXX |
| Incremental Cost Cliff (projected − current) | $X,XXX/month |
| Affected Resources | N |
| Affected Accounts | N |
| Services Analyzed | [list] |
| Regions Scanned | N |
### By Urgency
- CRITICAL: N resources — $X,XXX/month (currently incurring charges)
- HIGH: N resources — $X,XXX/month (entering ES within 3 months)
- MEDIUM: N resources — $X,XXX/month (entering ES within 3-6 months)
### By Service
- EKS: N clusters — $X,XXX/month
- RDS: N instances — $X,XXX/month
- ElastiCache: N nodes — $X,XXX/month
- OpenSearch: N instances — $X,XXX/month
- Lambda: N functions — $0 (security risk, no ES charge)
### Top Impacted Accounts
1. [account_name] ([account_id]) — $X,XXX/month
2. ...Step 5.2 — Generate CSV Artifact
Produce a CSV artifact with these columns:
account_id— AWS account IDaccount_name— Account name (if available from Organizations)resource_arn— Full ARN of the resourceresource_name— Human-readable identifier (cluster name, instance ID, function name)region— AWS regionservice— AWS service (EKS, RDS, Lambda, ElastiCache, OpenSearch)version— Current version/engine version/runtimeinstance_class— Instance type (for RDS, ElastiCache, OpenSearch) or N/Abilled_units— Billed units per hour and their unit (e.g.12 vCPU-hourfor 6 billed instances × 2 vCPUs,8 NIH,4 ACU-hour)eos_date— End of Standard Support date, orUNVERIFIEDeos_status— IN_EXTENDED_SUPPORT / APPROACHING_EOS / PAST_EXTENDED_SUPPORT / UNVERIFIEDes_year— Which pricing year the resource is in:1-2or3. For resources not yet in Extended Support (APPROACHING_EOS), use the sentinelN/A(they are not incurring ES charges yet, so no pricing year applies).current_monthly_es_cost— Monthly ES cost being incurred RIGHT NOW ($0 for APPROACHING_EOS; the Year 1-2/Year 3 rate for resources already in/past ES)projected_monthly_es_cost— Monthly ES cost once the resource enters Extended Support (full ES rate for APPROACHING_EOS; equals current for resources already in ES, or the Year 3 rate if it escalates within the window)es_start_date— Date the projected cost begins (the EOS date for APPROACHING_EOS; blank/N/Aif already incurring)annual_es_cost— Annual ES cost based onprojected_monthly_es_cost× 12 (the forward-looking run-rate)urgency— CRITICAL / HIGH / MEDIUM / UNVERIFIEDrecommended_target— Recommended upgrade versionupgrade_guide_url— Link to AWS migration documentation
Sort by projected_monthly_es_cost descending (surfaces the biggest future exposure first).
Title the artifact: "EOS Cost Impact Report — [date]"
Step 5.3 — Provide Upgrade Recommendations
For each affected version, include:
- Current version → Recommended target version
- Key considerations or breaking changes
- AWS documentation link for the upgrade path
- Estimated effort: mention sequential upgrade requirements if applicable
Step 5.4 — Lambda Security Risk Section (if applicable)
If deprecated Lambda runtimes were found:
## Security Risk: Deprecated Lambda Runtimes
These functions are running on deprecated runtimes that no longer receive
security patches. While no Extended Support charge applies, they represent
a security and compliance risk.
| Function | Runtime | Last Modified | Account |
|----------|---------|---------------|---------|
| ... | python3.8 | 2023-... | ... |Error Handling
| Error | Behavior |
| Role assumption fails for a linked account | Skip that account, note in report: "Account [ID] skipped — role assumption failed" |
| Service API returns AccessDenied | Skip that service/region, note: "Insufficient permissions for [service] in [region]" |
| Documentation search returns no EOS date | Mark version as UNVERIFIED (status, urgency and cost fields per references/billing-rules.md, section 6), include in report with note |
Pricing API returns no product after the GetAttributeValues usagetype retry | Set current_monthly_es_cost and projected_monthly_es_cost to "PRICING_UNAVAILABLE", do not estimate |
| No usage data for a usage-priced resource (Aurora Serverless v2) | Set the cost fields to USAGE_DEPENDENT with the rate and capacity range |
| No resources found for a service | Report: "No [service] resources found in scope" |
| Rate limiting (throttling) | Retry with exponential backoff (1s, 2s, 4s), max 3 retries |
| Timeout on large organization (1000+ accounts) | Report partial results, note which accounts were completed |
Tips
- Start with a single service for faster results — EKS is the simplest (flat per-cluster rate)
- RDS has the most complex pricing due to vCPU mapping and counting every billed instance (standbys and read replicas)
- Lambda has no cost impact but deprecated runtimes are a security risk worth flagging
- Year 3 doubles the rate for RDS and ElastiCache (EKS and OpenSearch stay flat), so a resource 24+ months past EOS costs twice what it did in Year 1-2
- Verify EOS dates from AWS documentation at runtime — deprecation schedules shift, so confirm each engine + version rather than trusting cached knowledge
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

