Repository navigation
Releases: headroom-project/headroom
Release list
v0.4.0
Changelog
Rules and catalog
Fixes
Other
Verify what you downloaded
# checksums
curl -LO https://github.com/headroom-project/headroom/releases/download/v0.4.0/checksums.txt
sha256sum -c checksums.txt --ignore-missing
# and that the checksums themselves came from this repository's release workflow
curl -LO https://github.com/headroom-project/headroom/releases/download/v0.4.0/checksums.txt.bundle
cosign verify-blob \
--bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github.com/headroom-project/headroom/.github/workflows/release.yml@refs/tags/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txtAn SBOM in SPDX form ships next to every archive.
headroom_web is the same analyzer compiled to WebAssembly. It is what the
playground on headroomcli.com runs, it is listed in checksums.txt like
every other artifact, and it opens no socket: it takes a plan document as a
string and returns the report. Instantiating it needs the wasm_exec.js
that ships with the Go toolchain the module was built with, which is why
that file is not published here.
v0.3.0
Changelog
Rules and catalog
Other
- f4d3dc0: chore(deps): bump goreleaser/goreleaser-action from 6.4.0 to 7.2.3 (#16) (@dependabot[bot])
- c9bfbfe: chore(gitignore): the local operating note stays out of a public tree (#17) (@nevesm)
- 7fb55ea: docs(changelog): v0.2.0 also ships --upload and the coloured report (#14) (@nevesm)
- 4584991: docs(changelog): v0.3.0, the update check (#18) (@nevesm)
Verify what you downloaded
# checksums
curl -LO https://github.com/headroom-project/headroom/releases/download/v0.3.0/checksums.txt
sha256sum -c checksums.txt --ignore-missing
# and that the checksums themselves came from this repository's release workflow
curl -LO https://github.com/headroom-project/headroom/releases/download/v0.3.0/checksums.txt.bundle
cosign verify-blob \
--bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github.com/headroom-project/headroom/.github/workflows/release.yml@refs/tags/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txtAn SBOM in SPDX form ships next to every archive.
v0.2.0
Carries three pull requests: --upload, colour in the report, and the work
below.
The release that came out of running the tool against seven real production
plans from a live Azure estate. It reported nothing on all seven and exited 0 on
all seven, including under --fail-on warning, and the infrastructure was not
idle: one of those plans puts 51,480 provisioned IOPS and 6,000 MB/s in front of
a VM whose sustained ceiling is 33,333 and 992.
Seven for seven was not a tuning problem. Almost everything below is a reason
the tool had for saying nothing.
Breaking changes
A plan that was silent may now produce findings, and --fail-on acts on
them. This is the point of the release and it is also the thing most likely to
turn a green pipeline red without any infrastructure having changed. If you gate
on --fail-on, expect to look at new findings before this upgrade rolls out
everywhere. Run once without the gate first.
--json emits [] instead of null when there are no findings. Anything
that special-cased the literal null needs to stop. Anything doing
jq 'length' starts working, which was the point: the shape of the document
used to change with the result.
The uploaded payload carries a new field, node.instance_count. A server
built against the previous ingest schema enforces additionalProperties: false
and rejects the whole report with a 400. Upgrade the receiving end before
upgrading the CLI, if you run your own.
AZ5 finding text changed, both title and summary, because it was claiming
more than the data supports for two of the three disk kinds. Anything matching on
the text of the report rather than on --json will not match.
xid now covers Azure and GCP. AWS identifiers hash exactly as before, on
purpose, so stored joins survive the upgrade. Azure and GCP resources that never
produced an xid now produce one.
Fixed
- The reference graph stops at a module boundary. A reference into a module
resolved to the module call, which has no type, so every rule that reasons
about a relationship between two resources went quiet whenever the two lived in
different modules. That is the normal arrangement in any repository of any
size, and it affected fifteen rule files. The graph now follows a module
output through to the resource behind it, including through nested modules and
through a module indexed dynamically, where terraform records no output name at
all. - A block whose value is
each.valuestates its reference infor_each.
Reading only the block left the edge unresolved on entirely idiomatic
terraform. - AZ2 read only the azurerm 4.x spelling of the autoscaling flag. Against a
3.x plan it fell back tonode_countand then stated "no autoscaling" about a
pool that autoscales, and a separate node pool that declares nonode_count
disappeared from the analysis. Measured on the same cluster planned both ways:
333 addresses of demand against 2,220. - Azure VM size and VPN gateway lookups were case sensitive while the disk
lookup in the same file was not. Azure is not, so a valid size written with a
different capital was unknown to the catalog with the correct figure sitting in
the table. - AZ5 called every excess "provisioned and billed". Standard SSD figures are
documented as "up to" and Premium SSD v2 does not price off the tier ladder,
so the money claim now prints only when every disk in the sum is a provisioned
tier. The ceiling claim is arithmetic and always prints. - A Premium SSD v2 disk that declares no IOPS counted as zero. Every one of
them gets 3,000 IOPS and 125 MB/s free of charge, and terraform makes both
attributes optional, so declaring nothing is the common case. azurerm_virtual_machinewas invisible to AZ5 and AZ6. The pre split
resource declares its disks inside the VM block and azurerm 4.0 removed it,
which does nothing about the estates that still plan it under 3.x.--jsonon a clean run emittednull.- The uploaded payload collapsed every
for_eachinstance into one node, so
three disks arrived as one. The local report was never affected, which is why
nothing caught it. - Cross repository stitching recognised AWS identifiers only.
Added
--upload, which sends the redacted payload to the headroom API after
printing the local report. It refuses to run alongside--dry-run, refuses to
send anything without a salt and has no flag that permits it, and refuses
without an API key. The bytes it sends are the bytes--dry-runprints, from
one function and one call site, so a customer can audit an upload by
rehearsing it. When the gate fires and the upload fails, exit 1 wins over exit
2: a network failure must not be able to launder a finding into a shrug.- Colour in the terminal report. Severity is coloured and nothing else is,
in eight colour ANSI. Stripping the escapes returns the uncoloured report byte
for byte.NO_COLORis honoured,--no-colorturns it off, and colour is off
automatically when stdout is not a terminal. --explain, which writes to stderr what each rule did with this plan:
what it reported, what it looked at and could not use, and why. The empty
report has always told the reader to run it and the flag did not exist, so
following the only instruction the tool gives printed a parse error and exited
2.- Three fixtures: a plan split across modules, the same AKS cluster planned by
azurerm 3.x, and the pre split VM resource. Every fixture before these was flat
and single provider, which is how the module boundary defect survived 199 green
tests. - 61 VM sizes in the Azure catalog, in six series: Esv6, Esv4, Easv5,
FXmdsv2, FXmsv2 and Basv2. Each carriessource,verified_atand
confidence, and the reasoning for every figure is in
docs/catalog-verification.md, including the three traps: the FX local storage
tab publishes 150,000 IOPS of ephemeral NVMe next to a 33,000 IOPS remote
ceiling, the AMD burstable halves at 32 vCPUs where the Intel one does not, and
Esv4 and Easv5 share the Esv5 IOPS with lower throughput. - A second uncached ceiling for the series that publish one, which governs
Ultra Disk and Premium SSD v2 and is about a third higher than the Premium SSD
pair. Judging a v2 disk against the lower pair understates the ceiling, and
understating a ceiling is how a rule invents a finding.
Internal
internal/extracthad no tests. It has some now.run.ps1 testsummarises and colours instead of printing every test, with
-Detailedfor the old behaviour.
Changelog
Rules and catalog
- e5f4b57: feat(report): colour the terminal output (#11) (@nevesm)
- e2368b5: feat: headroom analyze --upload (#12) (@nevesm)
Fixes
Verify what you downloaded
# checksums
curl -LO https://github.com/headroom-project/headroom/releases/download/v0.2.0/checksums.txt
sha256sum -c checksums.txt --ignore-missing
# and that the checksums themselves came from this repository's release workflow
curl -LO https://github.com/headroom-project/headroom/releases/download/v0.2.0/checksums.txt.bundle
cosign verify-blob \
--bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github.com/headroom-project/headroom/.github/workflows/release.yml@refs/tags/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txtAn SBOM in SPDX form ships next to every archive.
v0.1.0
Changelog
Rules and catalog
- bf34346: feat(rules): R1 to R8, AZ1 to AZ6 and GC1 to GC6 (Marcus Neves marcus-neves@outlook.com)
- ba1bea2: feat: capacity analyzer for terraform plan JSON (Marcus Neves marcus-neves@outlook.com)
Fixes
- e846a94: fix(ci): pin the two actions that publish no floating major tag (Marcus Neves marcus-neves@outlook.com)
- fcb7cbf: fix(release): sign to a cosign bundle, and stop skipping signing in the rehearsal (#10) (Marcus Neves marcus-neves@outlook.com)
- 6c40c32: fix: the domain is headroomcli.com (#9) (Marcus Neves marcus-neves@outlook.com)
Other
- 4d95047: build(release): goreleaser, sigstore signing, provenance and an installer (Marcus Neves marcus-neves@outlook.com)
- 85f5d88: ci(security): govulncheck, codeql, scorecard and dependency review (Marcus Neves marcus-neves@outlook.com)
- 8132e48: ci: pin every action to a commit sha (Marcus Neves marcus-neves@outlook.com)
- c15f720: ci: pin govulncheck to v1.7.0 (#7) (Marcus Neves marcus-neves@outlook.com)
- bfa1609: ci: resolve every action ref on the pull request (Marcus Neves marcus-neves@outlook.com)
- 986caab: ci: test on linux, macos and windows, and cross build every release target (Marcus Neves marcus-neves@outlook.com)
- 7988e09: test(cli): cover the command surface and lock two corrected ceilings (Marcus Neves marcus-neves@outlook.com)
- cc6270c: test(fixtures): real terraform plans for the three clouds (Marcus Neves marcus-neves@outlook.com)
- d0b579a: test(plan): assert the invariants Base actually holds (#6) (Marcus Neves marcus-neves@outlook.com)
- 8c9b42a: test(plan): fuzz the parser, and split Parse out of Load to make it possible (Marcus Neves marcus-neves@outlook.com)
- 130ae9e: test(rules): exercise every rule against the fixtures (Marcus Neves marcus-neves@outlook.com)
Verify what you downloaded
# checksums
curl -LO https://github.com/headroom-project/headroom/releases/download/v0.1.0/checksums.txt
sha256sum -c checksums.txt --ignore-missing
# and that the checksums themselves came from this repository's release workflow
curl -LO https://github.com/headroom-project/headroom/releases/download/v0.1.0/checksums.txt.bundle
cosign verify-blob \
--bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github.com/headroom-project/headroom/.github/workflows/release.yml@refs/tags/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txtAn SBOM in SPDX form ships next to every archive.