Repository navigation
fix: CloudFormation string numbers, template directories, block devices; Lambda arm64, Azure VM sizes, Cloud SQL regions - #103
Merged
Conversation
…vices; Lambda arm64, Azure VM sizes, Cloud SQL regions
CloudFormation:
- Numeric and boolean strings ("250", "true"), which CloudFormation
accepts and which every parameter reference produces, are converted
when they read back identically, so catalog arithmetic and pick()
no longer fail with "expected number, got string". RunNumber also
parses a numeric string, as its doc comment already claimed.
- A --path directory with templates and no .tf/.tofu files estimates
the templates (YAML/JSON with Resources plus AWSTemplateFormatVersion
or AWS:: types). Terraform directories are unchanged.
- EC2 BlockDeviceMappings map to root_block_device / ebs_block_device,
so their EBS volumes are priced. Lambda Architectures and
EphemeralStorage.Size are translated.
Catalog (mirrors the pricing API catalog):
- aws_lambda_function: arm64 detection works on the architectures list.
- Azure VM-sized kinds filter on armSkuName, not skuName.
- google_sql_database_instance: SKU location follows the region.
Engine: expressions see the region a resource is priced in as `region`
when the resource does not set that attribute.
andreacappelletti97
force-pushed
the
fix/demo-found-bugs
branch
from
September 29, 2026 17:49
692759d to
614cb77
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bugs found while building the c3x demo repo. Each has a regression test that fails on
mainand passes here.Depends on c3xdev/c3x-pricing-api#72. The catalog changes are identical in both repos, so the catalog-sync check here fails until that PR merges. Released CLIs get the catalog fixes from the pricing API. The catalog uses only expression functions that exist in released CLIs (
toJSON,contains, map literals,??,let).CloudFormation
AllocatedStorage: "250",MultiAZ: "false",Type: Numberparameters,--varoverrides) failed the whole estimate withexpected number, got stringorreflect: Call using string as type bool. The parser now converts strings that read back identically ("250","16.4","true"), recursively."8.0"and"007"stay strings, so versions and identifiers keep their spelling.RunNumberalso parses a numeric string, which its doc comment already claimed it did.--path <dir>with templates failed withno .tf, .tf.json, .tofu or .tofu.json files found. A directory with no Terraform/OpenTofu files now estimates every.yaml/.yml/.json/.templatefile directly inside it that has a non-emptyResourcessection plusAWSTemplateFormatVersionor anAWS::type.c3x-usage.yml, buildspecs and similar files are skipped. Terraform directories are unchanged:.tffiles take precedence.BlockDeviceMappingsEBS volumes were unpriced. The mapping on the root device (/dev/xvda,/dev/sda1, ...) becomesroot_block_deviceand the others becomeebs_block_deviceentries, which is the shape theaws_instancecatalog prices. Instance-store andNoDevicemappings are skipped. LambdaArchitecturesandEphemeralStorage.Sizeare also translated now.Before / after, template with m7i.xlarge + 50 GB root +
"200"GB extra gp3 and RDSAllocatedStorage: "250",MultiAZ: "false":Call using string as type bool, thenexpected number, got string). With the strings removed: $350.39/mo with no EBS lines.c3x estimate --path c3x-demo/cloudformation: beforeno .tf ... files found; after $362.79/mo, the same as--path .../template.yaml.Catalog / engine
architecturesis a list, so== "arm64"never matched. The check is nowtoJSON(default(architectures, "")) contains "arm64", and provisioned concurrency uses the same test. With 10M requests x 200 ms x 1024 MB in us-east-1: $35.33 -> $28.67/mo (Arm $0.0000133334 vs x86 $0.0000166667 per GB-s, https://aws.amazon.com/lambda/pricing/).skuName, which Azure spellsB2s,B2s v2,D2 v3for most series. Only some series useStandard_D2s_v5. In westeurope, 1,256 of 1,716 sizes matched nothing. VM-sized kinds now filter onarmSkuName. Before -> after in westeurope (Linux, per hour): B2s $0 -> $0.048, B2ms $0 -> $0.096, B2s_v2 $0 -> $0.105, B2als_v2 $0 -> $0.0524. The last two, and D2as_v5 ($0.196), are Cloud Services rows the scraper labels Linux. The scraper fix in c3x-pricing-api#72 brings them to $0.096 / $0.0432 / $0.104 on the next Azure scrape.in Frankfurt,in EMEA,in Singapore,in Northern Virginia). The mapping always asked forin Americas, so other regions fell back to us-central1 prices. A region -> location table now picks the right SKU; unknown regions keep the old behaviour. The engine also exposes the region a resource is priced in asregionwhen the resource does not set it, so a provider-level region works too. db-custom-2-7680 PostgreSQL zonal, 100 GB: europe-west3 $115.62 (fallback) -> $138.81; asia-southeast1 $115.62 -> $161.84; MySQL regional with the region from the provider block (europe-west3) $231.25 -> $277.47. All 920 region x engine x availability x SKU descriptions were checked against the live API.Checks
go test ./... -count=1, golangci-lint v2.13.2 (0 issues), gofumpt clean.go run ./cmd/verify_catalog: 164 live, 109 static, 1067 free, 0 zero, 0 drift, 0 nofix, 0 stale, 0 errored.