awsx

package
v1.12.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2026 License: Apache-2.0 Imports: 28 Imported by: 0

Documentation

Overview

Package awsx is everything that talks to AWS: finding what is running, and changing it.

Discovery records the prior state of each resource at the moment it is found, because that record is what makes the change reversible. It is deliberately read-only — nothing in the discover_*.go files mutates anything, so it is safe to run against production at any time, and `plan` does exactly that.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AccountID added in v1.10.0

func AccountID(ctx context.Context, cfg aws.Config) string

AccountID is the account these credentials belong to, or "unknown".

Never an error: it is a label on a plan, and failing a cost incident because STS was slow would be the wrong trade.

func EC2HourlyUSD added in v1.1.0

func EC2HourlyUSD(instanceType string) (float64, bool)

EC2HourlyUSD estimates the saving from stopping one instance.

The bool is the point of the signature: false means "no defensible estimate", which the caller must show as unknown. A new instance family that is not in the table reads as unknown rather than as free.

func NATGatewayHourlyUSD added in v1.1.0

func NATGatewayHourlyUSD() (float64, bool)

NATGatewayHourlyUSD is flat, so it needs no lookup — kept as a function for symmetry with the others, since callers switch over kinds.

func RDSHourlyUSD added in v1.1.0

func RDSHourlyUSD(instanceClass string) (float64, bool)

RDSHourlyUSD estimates the saving from stopping one database instance.

Single-AZ. A Multi-AZ deployment bills roughly double, and discovery does not currently record which it is — so this understates those, in the same direction as every other limit here.

Types

type Clients

type Clients struct {
	Region     string
	EC2        *ec2.Client
	ECS        *ecs.Client
	Lambda     *lambda.Client
	RDS        *rds.Client
	ASG        *autoscaling.Client
	ELB        *elasticloadbalancingv2.Client
	EKS        *eks.Client
	APIGateway *apigateway.Client
	// CloudFront is global, not regional. It is set on exactly one Clients so
	// a multi-region run does not find every distribution once per region and
	// plan the same disable five times.
	CloudFront *cloudfront.Client
}

Clients is one region's worth of AWS service clients, built once and shared by discovery and execution so both look at the same account through the same credentials.

func NewClients

func NewClients(cfg aws.Config, region string) *Clients

NewClients builds the per-region clients from a base config. CloudFront is left nil here: it is global, and exactly one Clients gets it.

func (*Clients) Discover

func (c *Clients) Discover(ctx context.Context) ([]model.Resource, []error)

Discover walks the account read-only. Per-service failures are collected rather than returned: a missing permission on one service should degrade the plan and say so, not leave the operator with nothing during an incident.

func (*Clients) WithCloudFront added in v1.10.0

func (c *Clients) WithCloudFront(cfg aws.Config) *Clients

WithCloudFront marks this Clients as the one that also walks CloudFront.

CloudFront has no regions. Whoever builds the per-region set calls this on exactly one of them; without it, a run across five regions would discover every distribution five times and plan five identical disables.

type Executor

type Executor struct {
	FinalSnapshot bool
	// contains filtered or unexported fields
}

Executor applies and undoes changes. Every Apply has a matching Restore, and neither ever deletes anything except a NAT gateway, which cannot be stopped.

func NewExecutor

func NewExecutor(clients map[string]*Clients) *Executor

NewExecutor takes the clients keyed by region. A resource in a region that is not in the map fails loudly rather than being skipped.

func (*Executor) Apply

func (e *Executor) Apply(ctx context.Context, a model.Action) error

Apply makes one change. Every kind handled here has a matching case in Restore -- an apply with no undo is a change this tool does not make.

func (*Executor) Restore

func (e *Executor) Restore(ctx context.Context, en model.Entry) error

Restore undoes one change from the recorded prior state, not from what the account looks like now: the account is the thing being repaired.

type Spend

type Spend struct {
	MonthToDateUSD float64
	Forecast       float64
	Start, End     time.Time
	Stale          bool
}

Spend reads month-to-date unblended cost, which is the number a threshold is usually written against.

Cost Explorer lags by several hours to a day. That is fine for "the bill is running away" and useless for "something spiked ten minutes ago" — a spike needs a CloudWatch alarm on a billing metric, or Budgets, to trigger this tool rather than this tool doing the polling. Said plainly here because a threshold that silently checks stale data is worse than no threshold.

func MonthToDate

func MonthToDate(ctx context.Context, c *costexplorer.Client, now time.Time) (Spend, error)

MonthToDate reads this month's spend and forecast from Cost Explorer. The numbers lag by hours, which is why Spend carries Stale: an incident decided on stale spend is a decision made on yesterday's account.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL