Skip to content

feat: add reserved-instances-check workflow - #214

Merged
HarmonicTons merged 4 commits into
masterfrom
feat/reserved-instances-check
Oct 22, 2026
Merged

HarmonicTons merged 4 commits into
masterfrom
feat/reserved-instances-check

Conversation

@HarmonicTons

@HarmonicTons HarmonicTons commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

AI;DR

Ajoute un workflow pour controller que nos DB + Elasticache tournent bien sur des instances réservées et pas on-demand. Pour éviter de payer pour rien, comme en ce moment depuis début septembre. Poste une message sur #ops quand une instance problématique est détectée.

What

New reusable workflow reserved-instances-check-v1 and composite action reserved-instances-check: compare the RDS and ElastiCache capacity in service with the active reservations, in size-flexible units per pool (reservation product + instance family, Multi-AZ counts double, the way AWS applies reservations), and post to Slack #ops when some capacity is not covered or when a reservation ends within expiry_warning_days. Nothing is posted when everything is covered, unless always_notify is set.

Resources created less than grace_days ago are ignored, and a resource meant to run without reservation for a while carries the tag reservation-exempt-until=YYYY-MM-DD: it is listed as exempted until that date, then reported again. The threshold min_uncovered_units applies to the pool, not to the instance, so a fleet of small instances is reported as a whole.

Context: the MySQL and PostgreSQL reservations expired on 2026-09-29 and nobody was told. Run offline against a copy of the account's current state (check.py --fixture-dir), the check reports exactly that: mysql / db.m6g 16 units uncovered, mysql / db.t4g 1 unit, postgresql / db.t4g 21.5 units, while Aurora and ElastiCache (renewed on 2026-10-08) are covered. The plan is to merge this, run the check from infra-ci to see the alert, then buy the reservations and see it clear.

The script only needs Python 3 and the AWS CLI, both present on the GitHub runners. The CI role needs the common_reservations_read_only policy, added in sencrop/infra-ci together with the scheduled caller.

yamllint and actionlint pass.

🤖 Generated with Claude Code

Weekly check of the RDS and ElastiCache capacity in service against the
active reservations, in size-flexible units per pool (reservation product
and instance family). Posts to Slack when some capacity is uncovered or
when a reservation ends within 60 days.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved coverage-accounting and inventory-handling errors can suppress alerts or abort monitoring, while notification logic can generate false alarms.

8 open issues
What changed in this PR

Adds a reusable reservation-monitoring workflow to detect uncovered RDS and ElastiCache capacity and warn about upcoming reservation expirations.

Changes:

  • Adds a Python checker with pooled capacity accounting, grace periods, dated exemptions, and offline fixture support.
  • Adds a composite action and reusable workflow for AWS access and conditional Slack notifications.
  • Documents the required IAM policy and a scheduled caller example.
File Description
README.md Documents reservation monitoring and caller configuration.
actions/​reserved-instances-check/​check.py Collects inventory, evaluates coverage, and generates reports.
actions/​reserved-instances-check/​action.yml Exposes checker inputs and report outputs.
.github/​workflows/​reserved-instances-check-v1.yml Configures AWS credentials and conditional Slack notifications.

Review effort: Balanced

Comment thread README.md Resolved
…s and transient statuses

Unknown or non-reservable instance sizes (db.serverless, 32xlarge and
above) are skipped and listed instead of aborting the run. Instances in
billable transient statuses such as rebooting or upgrading now count as
capacity; only non-billed statuses are excluded. A pool is reported only
on a positive gap, and an expired exemption alone no longer notifies.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…match SQL Server exactly

AWS applies reservations to the instances of an I/O-Optimized Aurora
cluster at 1.3 normalized units per standard unit, and SQL Server
reservations are not size-flexible.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Oracle License Included pooling can incorrectly treat differently sized reservations as coverage and suppress alerts.

1 open issue
2 resolved since last review

Review effort: Balanced

…ions on the exact class

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@HarmonicTons
HarmonicTons requested a balanced review from Copilot October 22, 2026 13:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Billing-sensitive reservation matching and cross-repository IAM and Slack integration require human validation against the target AWS account.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@HarmonicTons
HarmonicTons merged commit 93ea8a2 into master Oct 22, 2026
2 checks passed
@HarmonicTons
HarmonicTons deleted the feat/reserved-instances-check branch October 22, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants