Skip to content

fix(aws): EC2 per-pool expiry ignores size flexibility and keys non-RDS services without the service #450

Open

Description

@cristim

Summary

Two known limitations of the EC2 per-pool expiry adjustment in providers/aws/recommendations/expiry.go. They predate go#449, which documents them in its godoc.

  1. Size flexibility. Pools key on the exact instance type. A replacement of a different size in the same family is not credited, and an expiring RI of one size is not netted against coverage of another size. Size-flexible regional Linux/default-tenancy RIs are therefore over-deducted, which makes the tool re-buy. The RDS family path (family_nu.go) handles this with normalized units.
  2. Key collision. Non-RDS services share the commitmentPoolKey shape (expiry.go:~153). If two services used an identical ResourceType string in the same region, their expiring counts would combine.

Expected

  1. Credit and net EC2 size-flexible RIs in normalized units within the family, as the RDS family path does.
  2. Include the service in the pool key, or prove it already is unique per service.

Test

  1. A large RI expiring, replaced by two medium RIs, produces no re-buy.
  2. Two services with the same ResourceType string in one region keep their expiring counts separate.

Refs #346, #347.

Activity

  1. self-assigned this
    on Oct 16, 2026
  2. cristim commented on Oct 16, 2026

    @cristim
    MemberAuthor

    Claiming: working on this.

  3. cristim commented on Oct 16, 2026

    @cristim
    MemberAuthor

    Plan (go-450-ec2-expiry-sizeflex-key.md) findings on main:

    Part 1, the key collision, is not reachable today. The non-RDS services that share the 2-part region:type key have disjoint ResourceType shapes:

    • EC2 m5.large
    • ElastiCache cache.m5.large
    • OpenSearch m5.large.search
    • Redshift dc2.* / ra3.*
    • MemoryDB db.r6g.large

    RDS uses its own 4-part rdsPoolKey. Adding a service dimension would change poolKey, lookupPoolKey and commitmentPoolKey together, and with them the exported PoolCoverageMap shape that the ladder and the CLI read. So I'm doing a guard test over the real per-service shapes plus a comment on commitmentPoolKey, with no key change.

    Part 2, EC2 size flexibility, needs maintainer decisions before implementation, because it changes recommended purchase quantities. Proposal:

    Decisions needed:

    1. Attribution. Should every size in the family lose 100*d/T coverage points (uniform), or should d be weighted toward the expiring sizes?
    2. Lookback 0. Should cross-size netting apply even when CoverageLookbackDays == 0, i.e. on expiring-vs-expiring netting alone?
    3. Unknown dimensions. Should an unknown or empty platform, tenancy or scope count as non-flex? The proposed default is yes, which keeps today's exact-pool behaviour.

    Part 2 is about 400 lines and may split into two PRs. It changes no API, so the CLI caller picks it up on upgrade. I'm leaving part 2 open pending these answers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions