# Cost coverage

> FOR REVIEW — generated by StackToIT Assess. Architect review required before any decision.

Run `6f8f72b2-1c34-4cfc-8483-344c41245364` · source digest `sha256:19bfed642d5789ccada81b91d5c36e33175dcafd66dc46b1644ffa105d020000`

**Financial comparison: NOT AVAILABLE — no price source for 5 lines; 6 of 8 STACKIT lines have no price; 13 source resources are outside the model and can carry a charge; priced but outside the comparison (STACKIT, target only, no source line stands against them: 1 line, 72.70 EUR; STACKIT, priced lines of units that are not compared: 1 line, 91.97 EUR); the subtotal of one side is not a comparison and no saving is stated**

Not included in any total or comparison: traffic and usage that no assumption states, support, licences, operations and the one-off cost of the migration (what it costs to run both estates during the cutover is stated apart, as a one-off item); a scenario of what owning the estate costs, on either side, is not provided by this build.

1. Stage 1, coverage and uncertainties: 2 of 22 lines priced (source 0 of 14, STACKIT 2 of 8); the lines that have no price say why in the table of causes and the three coverage indicators below.
2. Stage 2, run-rate of the comparable services: not available, because no billable source resource is priced on both sides.
3. Stage 3, cost scenarios beyond the list prices (data egress, migration effort, operations): not provided by this build. Parallel running is stated apart: While both estates run (the cutover), per month of overlap: source no figure (no line of its estate is priced) and STACKIT 164.67 EUR, each in its own currency; no length of overlap is assumed (parallel_run_months in the assumption file states one); priced part only, so a lower bound (STACKIT: 2 of 8 lines priced). A one-off cost of the migration: in no total, comparison or saving.

## Why lines are not priced

reasons: 5 no cache · 4 target not chosen · 1 ambiguous · 1 use not stated. Different causes have different next actions: a refresh of the price cache fixes only the one marked CACHE_MISSING.

| Diagnostic | Lines | Families (lines) | What it is | Next action |
|---|---|---|---|---|
| `CACHE_MISSING` | 5 | google_secret_manager_secret 4, google_pubsub_topic 1 | The price key is known and no price source supplied its record: no price cache, a price family the cache lacks, or a record it refused. | fill the price cache once, online: `stacktoit prices refresh` (the commands for each missing price family are in the price source statement); the assessment itself stays offline. |
| `TARGET_NOT_CHOSEN` | 4 | PostgreSQL Flex 2, RabbitMQ 1, SKE 1 | The draft leaves the plan, flavor, storage class or key protection that names the SKU to a variable without a value, so no SKU is named and no price is made up. | state the choice in the assumption file (--assumptions FILE) or as the answer cost.target_choice of the inputs file (--inputs FILE): variable target_choice, with the subject and an example value that each line names, or answer the request that changes the draft; the line is then priced on your value and says so. A refresh does not help. |
| `AMBIGUOUS` | 1 | Secrets Manager 1 | More than one price or tier fits these lines and none is picked: what chooses between them is not a fact of the source or the draft, or the vendor does not define it. | each line says what chooses between the prices: state it where the line names the variable (os, tenancy, licence), in the assumption file or as the answer cost.<variable> of the inputs file; where the vendor defines no choice (a tier of a service) the line stays unpriced until it does. A refresh does not help. |
| `USAGE_NOT_STATED` | 1 | Object Storage 1 | The price is per unit of use (data, requests, capacity units, queries) and no source states the use, so the quantity is not multiplied; it is neither 0 nor 1. | state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.<variable> of the inputs file (--inputs FILE), in the variable and unit the line names (data_transfer, usage_quantity, volume_size, log_ingestion; assumptions-template.yaml lists them); the line is then priced on your figure and says so. A line that names none (the storage of a broker, the I/O requests of an Aurora cluster) has no input for it in this build. Without a figure the line has its price and no amount, and is in no total. |

The diagnostic of each line is the `diagnostic` field of `financial/cost-model.json`. A line that is not priced for another reason keeps its state and has none.

**Price source: the lines that need gcp/PubSub/global, gcp/SecretManager/global are not priced.**

| Price family (as `stacktoit prices status` names it) | Why | Rungs tried | Command |
|---|---|---|---|
| `gcp/PubSub/global` | the price cache holds no record of it | 1 price cache: the cache at the default location holds no record of it (the cache was last filled 2026-11-02); 2 release snapshot: none in this build; 3 auto-fetch: no program to fetch with: stacktoit-prices was not found next to this binary or on PATH; 4 UNPRICED | `stacktoit prices refresh --provider gcp --region global --offer PubSub` |
| `gcp/SecretManager/global` | the price cache holds no record of it | 1 price cache: the cache at the default location holds no record of it (the cache was last filled 2026-11-02); 2 release snapshot: none in this build; 3 auto-fetch: no program to fetch with: stacktoit-prices was not found next to this binary or on PATH; 4 UNPRICED | `stacktoit prices refresh --provider gcp --region global --offer SecretManager` |

A run fetches a missing price family by itself unless it is offline; what is named above could not be fetched or found, and the commands fill it by hand. Add --price-cache DIR to the command and to assess when you use a cache directory of your own.

These are list prices only: no quantity is read and no total is built from them here; the quantities, amounts and totals of the priced families are in financial/cost-model.json, which computes a usage or an egress only where the assumption file states it.

An initial infrastructure cost estimate under explicit assumptions (the scenario and the assumption file this model names), not a bill: list prices (net, no discount, no Spot, no savings plan, no private price) times quantities the source or the assumption file states. A total is FULL only when every line of its scope is priced; a line that cannot be priced says why and is never filled in, and an unknown quantity is neither 0 nor 1. A savings percentage is given only for the same scope, in one currency (or with an exchange rate that names its source and date), with every line of both sides priced. No usage, traffic, request or egress cost is computed unless the assumption file states the use of one month: a line priced on a stated use is an assumption and says so, and without it the line has its price and no amount. No support, licence, operations or migration labour cost is computed. The one one-off item the model states is what both estates cost while they run side by side during the cutover (parallel_run_months of the assumption file): it is stated apart and is in no total, comparison or saving.

Scenario: **STANDARD_730H**, 730 hours (the labelled standard month of 730 hours, the same on both sides). The lines are in `financial/cost-model.json` and in `financial/priced-resources.csv`.

## Price sources

| Side | Source | Status | sha256 | Note |
|---|---|---|---|---|
| SOURCE | `gcp/PubSub/global` | NOT_AVAILABLE |  | the price cache holds no Google Cloud PubSub catalog for global: its lines cannot be priced (run `stacktoit prices refresh --provider gcp --region global --offer PubSub`, with your API key in STACKTOIT_GCP_BILLING_API_KEY) |
| SOURCE | `gcp/SecretManager/global` | NOT_AVAILABLE |  | the price cache holds no Google Cloud SecretManager catalog for global: its lines cannot be priced (run `stacktoit prices refresh --provider gcp --region global --offer SecretManager`, with your API key in STACKTOIT_GCP_BILLING_API_KEY) |
| TARGET | `stackit` | USED | `94244fec5b573614dcff15f79238ce4a0e60cf197768be287e45092d7e1e61ca` | retrieved 2026-10-26T18:27:45Z; net list price; supplied by the price cache |

## Lines by pricing state

22 lines in all: 14 of the source, 8 of the target.

| State | Lines | Meaning |
|---|---|---|
| AMBIGUOUS | 1 | More than one price fits and none is picked. |
| PRICED | 2 | A price record and a known quantity give an amount. |
| PRICE_NOT_FOUND | 9 | The key names a price and the price list in force has none (or the region or purchasing option rules it out): never free. |
| PRICE_SOURCE_ABSENT | 5 | No price source was available for this line. |
| QUANTITY_UNKNOWN | 1 | A price is known and the quantity is not: neither zero nor one. |
| TARGET_NOT_CHOSEN | 4 | The target design does not choose what the price needs. |

## Lines by class

Every line is one of four classes, so that a known figure is not read as an estimate or an assumption, and a line that is not computed is not read as zero. The class is the `class` column of `financial/priced-resources.csv`.

| Class | Lines | Meaning |
|---|---|---|
| KNOWN | 0 | list price × a quantity read from the source or the draft; nothing else assumed |
| ESTIMATE | 2 | a list price with an assumption the model states: the hours of the scenario (730 h in the standard month) on a per-hour rate |
| ASSUMPTION | 0 | a quantity or a class is assumed (an operating system, a tenancy, a performance class); the assumption is named on the line |
| OUT_OF_MODEL | 20 | not computed: not zero and not free; the line says what is missing |

## Coverage: how much of the estate the model can price

**Billable coverage: which source resources can carry a price.** Most source resources carry no charge of their own (a security group rule, an IAM role, a route), so the share of source resources that have a line is not the share of the estate that is priced. Of the 33 source resources, 20 are or may be billed. The source resources of the cost model are the managed resources of the source that no count or for_each of 0 switches off; the resources scanned of the first screen also count the switched-off ones, so its figure can be larger.

| Source resources | Count | Meaning |
|---|---|---|
| With a price rule | 7 | Of a type this build prices: the model has a line for them (a line can still lack a price or a quantity: see the next tables). |
| No charge of its own | 13 | Of a type the source cloud bills nothing for (a firewall or security group rule, an IAM role): there is nothing to price, and they are not out of the model. |
| Out of the model | 13 | May be billed, and this build has no price rule for the type, or does not classify it: its cost is not computed, never zero and never free. |

Out of the model, by type: google_cloudbuild_trigger (3), google_secret_manager_secret_iam_binding (2), google_storage_bucket_iam_member (2), google_cloud_run_service_iam_policy (1), google_firebase_hosting_site (1), google_firebase_project (1), google_project_service (1), google_sql_database (1), google_sql_user (1).

**Price coverage: which lines have a price.** Of the 22 lines of the model, both sides.

| Lines | Count | Meaning |
|---|---|---|
| Price found | 2 | The line carries a price record (a rate from a price list), whether or not its quantity is known. |
| No price | 20 | No rate: the reason is each of the rows below. |
| PRICE_NOT_FOUND | 9 | The key names a price and the price list in force has none (or the region is not stated): never free. |
| PRICE_SOURCE_ABSENT | 5 | No price source was available for the line (no cache, no snapshot, no fetch). |
| TARGET_NOT_CHOSEN | 4 | The target design does not choose what the price needs. |
| AMBIGUOUS | 1 | More than one price fits and none is picked. |
| QUANTITY_UNKNOWN | 1 |  |

Lines with a price found, by side: source 0 of 14, target 2 of 8. Of the lines without a price, by diagnostic: CACHE_MISSING (5), TARGET_NOT_CHOSEN (4), AMBIGUOUS (1), USAGE_NOT_STATED (1) (a refresh of the price cache fixes only CACHE_MISSING).

**Usage coverage: which priced lines have a quantity.** Of the 2 lines that have a price.

| Priced lines | Count | Meaning |
|---|---|---|
| Quantity known | 2 | The line has an amount; 0 of them rest on a quantity the assumption file states. |
| Quantity unknown | 0 | QUANTITY_UNKNOWN: the price is known, the quantity (a usage, a traffic, a size the source does not state) is not; neither zero nor one. |

A subtotal is the sum of the list prices of the lines that are priced, for the resources this build prices. It is not the cost of running the estate: usage and traffic that no assumption states, support, licences, operation and the effort of the migration are not in it. A difference between the source and the target subtotal is the difference of those list prices over the same resources, in one currency; it is not the saving, or the cost, of the migration.

## Estimated monthly cost for the resources that could be compared (730 h, list prices)

A saving or an increase is stated only over the source resources that both sides price in full (0 resources); the others are under Cost groups below with why they are not computed.

No line is summed: the computed subtotal is empty. A line of the class OUT_OF_MODEL is not computed, is in no sum and is never filled in as zero.

### Computed subtotal

No source unit is priced on both sides: there is no computed subtotal.

Source against target over the computed units: NOT_COMPARED; saving of the target not given (no source unit is priced on both sides, so there is no computed subtotal to compare).

Outside this comparison: STACKIT, target only, no source line stands against them: 1 line, 72.70 EUR; STACKIT, priced lines of units that are not compared: 1 line, 91.97 EUR. The target-only lines are in the priced part of the STACKIT total, and no saving includes them.

A difference stated here is a difference over the compared part only, not a saving of the estate. What the compared part leaves out: priced but outside the comparison (STACKIT, target only, no source line stands against them: 1 line, 72.70 EUR; STACKIT, priced lines of units that are not compared: 1 line, 91.97 EUR); without a price: 14 source lines (9 PRICE_NOT_FOUND, 5 PRICE_SOURCE_ABSENT), 6 STACKIT lines (1 AMBIGUOUS, 1 QUANTITY_UNKNOWN, 4 TARGET_NOT_CHOSEN); reasons: 5 no cache · 4 target not chosen · 1 ambiguous · 1 use not stated; 20 of 20 billable source resources not compared; usage and traffic that no assumption states, support, licences, operations and the one-off costs of the migration are in no figure (the cost of both estates running side by side during the cutover is stated apart, as a one-off item).

A difference between the source and the target subtotal is the difference of those list prices over the same resources, in one currency; it is not the saving, or the cost, of the migration.

### Technical mapping

5 pairs of the computed units and of the units that are only partly priced (their basis says how many components are priced) are in `financial/mapping.csv` with the vCPU, memory, CPU model, disk, IOPS, throughput and high availability each side states. A machine type is one of the types of the catalogue with at least the vCPUs and memory of the source (a burstable source may be offered shared types); a storage class is the one the draft names (the customer's answer or the variable's default), shown with the catalogue's own IOPS and throughput. This table states sizes; it is not a statement about the performance of the target against the source (no benchmark was run, and a CPU model that a side does not state is shown as not stated).

## Totals

The state of an estate row is the estate's: PARTIAL while any line of any source resource the model knows is not priced, a resource outside the modelled part included. Its amount is the modelled infrastructure subtotal (3 of 33 source resources): the sum of the lines that are priced; N is the number of source resources with a priced line and M all the source resources the model knows (a source resource is a Terraform resource; one migration unit can stand for several). A resource with no priced line is not in it, and the lines of a counted resource that are not priced are counted beside the amount and never filled in; so it is not the cost of the estate.

| Scope | Side | State | Amount | Priced lines | Not priced |
|---|---|---|---|---|---|
| estate (33 source resources), priced part: modelled infrastructure subtotal (3 of 33 source resources) | SOURCE | NONE | none | 0 | 14 |
| estate (33 source resources), priced part: modelled infrastructure subtotal (3 of 33 source resources) | TARGET | PARTIAL | 164.67 EUR | 2 | 6 |
| service containers | TARGET | PARTIAL | 72.70 EUR | 1 | 1 |
| service database | SOURCE | NONE | none | 0 | 3 |
| service database | TARGET | PARTIAL | 91.97 EUR | 1 | 2 |
| service messaging | SOURCE | NONE | none | 0 | 1 |
| service messaging | TARGET | NONE | none | 0 | 1 |
| service object_storage | SOURCE | NONE | none | 0 | 1 |
| service platform | TARGET | NONE | none | 0 | 1 |
| service secrets | SOURCE | NONE | none | 0 | 4 |
| service serverless | SOURCE | NONE | none | 0 | 5 |
| service storage | TARGET | NONE | none | 0 | 1 |

FULL: every line of the scope is priced. PARTIAL: the priced lines are summed; the others are counted and never filled in. NONE: no line of the scope has an amount.

## Comparison of source and target

| Scope | Comparability | Saving or increase | Why |
|---|---|---|---|
| estate (33 source resources), priced part: modelled infrastructure subtotal (3 of 33 source resources) | TARGET_ONLY | not given | TARGET_ONLY: the source has no priced component. Outside this comparison: STACKIT, target only, no source line stands against them: 1 line, 72.70 EUR. The target-only lines are in the priced part of the STACKIT total, and no saving includes them. |
| service containers | TARGET_ONLY | not given | TARGET_ONLY: there is no source total. Outside this comparison: STACKIT, target only, no source line stands against them: 1 line, 72.70 EUR. The target-only lines are in the priced part of the STACKIT total, and no saving includes them. |
| service database | TARGET_ONLY | not given | TARGET_ONLY: the source has no priced component |
| service messaging | COMPARABLE | not given | NONE: neither side has a priced component |
| service object_storage | SOURCE_ONLY | not given | SOURCE_ONLY: there is no target total |
| service platform | TARGET_ONLY | not given | TARGET_ONLY: there is no source total |
| service secrets | SOURCE_ONLY | not given | SOURCE_ONLY: there is no target total |
| service serverless | SOURCE_ONLY | not given | SOURCE_ONLY: there is no target total |
| service storage | TARGET_ONLY | not given | TARGET_ONLY: there is no source total |

A difference between the source and the target subtotal is the difference of those list prices over the same resources, in one currency; it is not the saving, or the cost, of the migration.

A difference stated here is a difference over the compared part only, not a saving of the estate. What the compared part leaves out: priced but outside the comparison (STACKIT, target only, no source line stands against them: 1 line, 72.70 EUR; STACKIT, priced lines of units that are not compared: 1 line, 91.97 EUR); without a price: 14 source lines (9 PRICE_NOT_FOUND, 5 PRICE_SOURCE_ABSENT), 6 STACKIT lines (1 AMBIGUOUS, 1 QUANTITY_UNKNOWN, 4 TARGET_NOT_CHOSEN); reasons: 5 no cache · 4 target not chosen · 1 ambiguous · 1 use not stated; 20 of 20 billable source resources not compared; usage and traffic that no assumption states, support, licences, operations and the one-off costs of the migration are in no figure (the cost of both estates running side by side during the cutover is stated apart, as a one-off item).

## While both estates run

While both estates run (the cutover), per month of overlap: source no figure (no line of its estate is priced) and STACKIT 164.67 EUR, each in its own currency; no length of overlap is assumed (parallel_run_months in the assumption file states one); priced part only, so a lower bound (STACKIT: 2 of 8 lines priced). A one-off cost of the migration: in no total, comparison or saving.

| Estate | State | Per month of overlap | Lines priced |
|---|---|---|---|
| SOURCE | NONE | no figure | 0 of 14 |
| TARGET | PARTIAL | 164.67 EUR | 2 of 8 |

Both estates run while the migration is cut over. These are the monthly list-price subtotals of the priced lines of each side, each in the currency of its own side (no exchange rate is applied), so they are a lower bound: a line without a price is not in them. The cost of both estates running is a one-off cost of the migration: it is in no total, no comparison and no saving, and it is not the difference between the two estates.

## Cost groups

Every source unit is in one of three groups. Computed: every line of it, on both sides, has an amount; only these lines make the computed subtotals, so the source and the target subtotal cover the same units and may be compared. Quantity unknown: the price of each open line is known and its quantity is not; the quantity that is needed is named. Not computed: a unit of a type out of the model (no quantity driver; the coverage table counts those apart, by type), a unit the partial draft refuses for a missing input (the coverage table counts those apart as refused), a unit with no line on one side, or a line without a price record; listed by resource with the reason, never zero and never free. It holds every unit counted as out of the model or as refused and the units priced on one side only, so its count is the larger.


### Price known, quantity unknown (0)

None.

### Not computed (18)

| Source units | Why it is not computed (not zero) |
|---|---|
| `google_cloud_run_service_iam_policy.server_noauth` | no quantity driver for google_cloud_run_service_iam_policy in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_cloud_run_v2_job.migrate, google_cloud_run_v2_service.server` | SOURCE: 0 components priced, 5 not priced: run cpu time (google_cloud_run_v2_job.migrate) PRICE_NOT_FOUND; run memory time (google_cloud_run_v2_job.migrate) PRICE_NOT_FOUND; run cpu time (google_cloud_run_v2_service.server) PRICE_NOT_FOUND; run memory time (google_cloud_run_v2_service.server) PRICE_NOT_FOUND; run requests (google_cloud_run_v2_service.server) PRICE_NOT_FOUND. TARGET: 1 component priced, 1 not priced: node pool hours (stackit_ske_cluster.containers.node_pool.workloads) TARGET_NOT_CHOSEN; the priced component alone sums to 72.70 EUR. These sums cover the priced components only: a partial figure, not the cost of this resource, and in no computed subtotal, comparison or saving.; source:google_cloud_run_v2_job.migrate:run_cpu_time: PRICE_NOT_FOUND: GCP region not known: location comes from a variable's default, which is not a fact of the source: choose region in the assumption file (--assumptions FILE) or as the answer cost.region of the inputs file (--inputs FILE); second cause, open once this one is closed: the quantity is not known: the time the tasks of a job run per month is a measurement of use (the billable instance time of Cloud Run); the source does not state it; to price it, state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.usage_quantity of the inputs file (--inputs FILE): variable usage_quantity, unit instance-hour, subject google_cloud_run_v2_job.migrate.instance_time; source:google_cloud_run_v2_job.migrate:run_memory_time: PRICE_NOT_FOUND: the same reason as source:google_cloud_run_v2_job.migrate:run_cpu_time; source:google_cloud_run_v2_service.server:run_cpu_time: PRICE_NOT_FOUND: GCP region not known: location comes from a variable's default, which is not a fact of the source: choose region in the assumption file (--assumptions FILE) or as the answer cost.region of the inputs file (--inputs FILE); second cause, open once this one is closed: the quantity is not known: the time the instances of a service are billed per month is a measurement of use (the billable instance time of Cloud Run); the source does not state it; to price it, state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.usage_quantity of the inputs file (--inputs FILE): variable usage_quantity, unit instance-hour, subject google_cloud_run_v2_service.server.instance_time; source:google_cloud_run_v2_service.server:run_memory_time: PRICE_NOT_FOUND: the same reason as source:google_cloud_run_v2_service.server:run_cpu_time; source:google_cloud_run_v2_service.server:run_requests: PRICE_NOT_FOUND: GCP region not known: location comes from a variable's default, which is not a fact of the source: choose region in the assumption file (--assumptions FILE) or as the answer cost.region of the inputs file (--inputs FILE); second cause, open once this one is closed: the quantity is not known: the requests a service serves per month are a measurement of use; the source does not state them; to price it, state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.usage_quantity of the inputs file (--inputs FILE): variable usage_quantity, unit request, subject google_cloud_run_v2_service.server.requests; the free allowance of the account (Cloud Run free tier) is not subtracted: the price shown is the first paid tier; target:stackit_ske_cluster.containers.node_pool.workloads:node_pool_hours: TARGET_NOT_CHOSEN: NOT_ASSESSED: the draft does not choose the server flavor (node_pools.machine_type is var.containers_machine_type): no SKU is named; to name the SKU of this line, state the value of node_pools.machine_type in the assumption file (--assumptions FILE) or as the answer cost.target_choice of the inputs file (--inputs FILE): variable target_choice, subject stackit_ske_cluster.containers.node_pool.workloads, value a server flavor such as "g2i.4"; target:stackit_ske_cluster.containers:cluster_hours: TARGET_ONLY: priced at 72.70 EUR and counted in the priced part of the STACKIT total, but the source side holds no line of its family to stand against: outside the comparison, in no saving |
| `google_cloudbuild_trigger.activategcb` | no quantity driver for google_cloudbuild_trigger in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_cloudbuild_trigger.init` | no quantity driver for google_cloudbuild_trigger in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_cloudbuild_trigger.placeholder` | no quantity driver for google_cloudbuild_trigger in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_firebase_hosting_site.client` | no quantity driver for google_firebase_hosting_site in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_firebase_project.default` | no quantity driver for google_firebase_project in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_pubsub_topic.faux` | source:google_pubsub_topic.faux.data:pubsub_data: PRICE_SOURCE_ABSENT: the price cache holds no Google Cloud PubSub catalog for global: its lines cannot be priced (run `stacktoit prices refresh --provider gcp --region global --offer PubSub`, with your API key in STACKTOIT_GCP_BILLING_API_KEY); second cause, open once this one is closed: the quantity is not known: the data a topic delivers per month is a measurement of use; the source does not state it; to price it, state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.data_transfer of the inputs file (--inputs FILE): variable data_transfer, unit GiB, subject google_pubsub_topic.faux.data; the price shown is the first paid tier of the message delivery SKU; subscriptions' own delivery and retained storage are not in the line; target:stackit_rabbitmq_instance.messaging:service_plan_hours: TARGET_NOT_CHOSEN: NOT_ASSESSED: the draft does not choose the rabbitmq plan (plan_name is var.rabbitmq_plan_name): no SKU is named; to name the SKU of this line, state the value of plan_name in the assumption file (--assumptions FILE) or as the answer cost.target_choice of the inputs file (--inputs FILE): variable target_choice, subject stackit_rabbitmq_instance.messaging (or the source unit it stands for), value a plan of the catalogue such as "stackit-rabbitmq-2.4.10-single" |
| `google_secret_manager_secret.django_admin_password, google_secret_manager_secret.django_settings` | source:google_secret_manager_secret.django_admin_password:secret_access: PRICE_SOURCE_ABSENT: the price cache holds no Google Cloud SecretManager catalog for global: its lines cannot be priced (run `stacktoit prices refresh --provider gcp --region global --offer SecretManager`, with your API key in STACKTOIT_GCP_BILLING_API_KEY); second cause, open once this one is closed: the quantity is not known: the access operations of a secret per month are a measurement of use; the source does not state them; to price it, state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.usage_quantity of the inputs file (--inputs FILE): variable usage_quantity, unit operation, subject google_secret_manager_secret.django_admin_password.operations; rotation notifications are billed apart and are not in the line; source:google_secret_manager_secret.django_admin_password:secret_versions: PRICE_SOURCE_ABSENT: the price cache holds no Google Cloud SecretManager catalog for global: its lines cannot be priced (run `stacktoit prices refresh --provider gcp --region global --offer SecretManager`, with your API key in STACKTOIT_GCP_BILLING_API_KEY); second cause, open once this one is closed: the quantity is not known: the active versions of a secret per month, times the locations it is replicated to, are a measurement of use; the source does not state them (the secret has 1 replica locations); to price it, state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.usage_quantity of the inputs file (--inputs FILE): variable usage_quantity, unit version, subject google_secret_manager_secret.django_admin_password.versions; the free allowance of the account is not subtracted: the price shown is the first paid tier; the line counts version-locations; source:google_secret_manager_secret.django_settings:secret_access: PRICE_SOURCE_ABSENT: the price cache holds no Google Cloud SecretManager catalog for global: its lines cannot be priced (run `stacktoit prices refresh --provider gcp --region global --offer SecretManager`, with your API key in STACKTOIT_GCP_BILLING_API_KEY); second cause, open once this one is closed: the quantity is not known: the access operations of a secret per month are a measurement of use; the source does not state them; to price it, state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.usage_quantity of the inputs file (--inputs FILE): variable usage_quantity, unit operation, subject google_secret_manager_secret.django_settings.operations; rotation notifications are billed apart and are not in the line; source:google_secret_manager_secret.django_settings:secret_versions: PRICE_SOURCE_ABSENT: the price cache holds no Google Cloud SecretManager catalog for global: its lines cannot be priced (run `stacktoit prices refresh --provider gcp --region global --offer SecretManager`, with your API key in STACKTOIT_GCP_BILLING_API_KEY); second cause, open once this one is closed: the quantity is not known: the active versions of a secret per month, times the locations it is replicated to, are a measurement of use; the source does not state them (the secret has 1 replica locations); to price it, state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.usage_quantity of the inputs file (--inputs FILE): variable usage_quantity, unit version, subject google_secret_manager_secret.django_settings.versions; the free allowance of the account is not subtracted: the price shown is the first paid tier; the line counts version-locations; target:stackit_secretsmanager_instance.migrated_secrets:list_price: AMBIGUOUS: 5 public SKUs match the Secrets Manager version hour (Secrets Manager-100-EU01, Secrets Manager-100k-EU01, Secrets Manager-10k-EU01, Secrets Manager-1M-EU01, Secrets Manager-1k-EU01): none is picked; the tier is read as the number of secret versions of the instance, which the draft does not state, and which the price list (1.0.44, page Security) and the documentation of the service (FAQ, 2026-11-02: "You pay per secret version") do not define: no tier is assumed |
| `google_secret_manager_secret_iam_binding.django_admin_password` | no quantity driver for google_secret_manager_secret_iam_binding in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_secret_manager_secret_iam_binding.django_settings` | no quantity driver for google_secret_manager_secret_iam_binding in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_sql_database.database` | no quantity driver for google_sql_database in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_sql_database_instance.postgres` | SOURCE: 0 components priced, 3 not priced: storage capacity (billed per GB) (google_sql_database_instance.postgres.storage) PRICE_NOT_FOUND; sql ram hours (google_sql_database_instance.postgres) PRICE_NOT_FOUND; sql vcpu hours (google_sql_database_instance.postgres) PRICE_NOT_FOUND. TARGET: 1 component priced, 2 not priced: storage capacity (billed per GB) (stackit_postgresflex_instance.postgres) TARGET_NOT_CHOSEN; storage class fee (billed per disk) (stackit_postgresflex_instance.postgres) TARGET_NOT_CHOSEN; the priced component alone sums to 91.97 EUR. These sums cover the priced components only: a partial figure, not the cost of this resource, and in no computed subtotal, comparison or saving.; source:google_sql_database_instance.postgres.storage:db_storage: PRICE_NOT_FOUND: GCP region not known: region comes from a variable's default, which is not a fact of the source: choose region in the assumption file (--assumptions FILE) or as the answer cost.region of the inputs file (--inputs FILE); second cause, open once this one is closed: the quantity is not known: settings.disk_size is not stated: the instance starts at the size Cloud SQL chooses and grows with disk_autoresize; no committed-use discount is applied: the line is the list price; backups, the IPv4 address and network egress are billed apart and are not in the lines; source:google_sql_database_instance.postgres:sql_ram_hours: PRICE_NOT_FOUND: GCP region not known: region comes from a variable's default, which is not a fact of the source: choose region in the assumption file (--assumptions FILE) or as the answer cost.region of the inputs file (--inputs FILE); no committed-use discount is applied: the line is the list price; backups, the IPv4 address and network egress are billed apart and are not in the lines; source:google_sql_database_instance.postgres:sql_vcpu_hours: PRICE_NOT_FOUND: the same reason as source:google_sql_database_instance.postgres:sql_ram_hours; target:stackit_postgresflex_instance.postgres:db_storage: TARGET_NOT_CHOSEN: NOT_ASSESSED: the draft does not choose the PostgreSQL Flex storage class (storage.class is var.postgresflex_storage_class): no SKU is named; to name the SKU of this line, state the value of storage.class in the assumption file (--assumptions FILE) or as the answer cost.target_choice of the inputs file (--inputs FILE): variable target_choice, subject stackit_postgresflex_instance.postgres.storage_class, value a storage class such as "premium-perf6-stackit", or answer the request target.postgres.storage of the run (review/inputs.yaml), which also changes the draft; target:stackit_postgresflex_instance.postgres:db_storage_perf_class: TARGET_NOT_CHOSEN: the same reason as target:stackit_postgresflex_instance.postgres:db_storage |
| `google_sql_user.django` | no quantity driver for google_sql_user in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_storage_bucket.media` | source:google_storage_bucket.media.storage:bucket_storage: PRICE_NOT_FOUND: GCP region not known: location comes from a variable's default, which is not a fact of the source: choose region in the assumption file (--assumptions FILE) or as the answer cost.region of the inputs file (--inputs FILE); second cause, open once this one is closed: the quantity is not known: the data a bucket holds per month is a measurement of use; the source does not state it; to price it, state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.volume_size of the inputs file (--inputs FILE): variable volume_size, unit GiB, subject google_storage_bucket.media.storage; the line is the storage of the bucket's default class; operations, retrieval, early-deletion and data transfer charges are billed apart and are not in it; target:stackit_objectstorage_bucket.media:list_price: QUANTITY_UNKNOWN: the list price of ST-0010801 is known (0.00003697772 EUR per Gigabyte Hours); the quantity is the gigabyte-hours the bucket holds, a measurement of use the draft does not state, so it is not multiplied; to price it, state the average gigabytes one bucket holds in the assumption file (--assumptions FILE) or as the answer cost.volume_size of the inputs file (--inputs FILE): variable volume_size, unit GB, subject stackit_objectstorage_bucket.media (or the source unit it stands for; another data unit converts); without it the line stays unpriced |
| `google_storage_bucket_iam_member.automation` | no quantity driver for google_storage_bucket_iam_member in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `google_storage_bucket_iam_member.server` | no quantity driver for google_storage_bucket_iam_member in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |
| `module.project_services.google_project_service.project_services` | no quantity driver for google_project_service in this build: its cost is not computed (it is not zero); no SOURCE line: the model does not compute the cost of the source; no TARGET line: the draft has no priced component for it |

### No charge of its own (13)

| Source units | Why there is nothing to price |
|---|---|
| `google_project_iam_member.automation_permissions` | NO_CHARGE: google_project_iam_member has no charge of its own (see the billable coverage): there is nothing to price, it is billed, if at all, through the resource it belongs to or configures, and it is not out of the model (Google Cloud, Identity and Access Management pricing (read 2026-11-05): "All use of Identity and Access Management API is free of charge") |
| `google_project_iam_member.client_permissions` | NO_CHARGE: google_project_iam_member has no charge of its own (see the billable coverage): there is nothing to price, it is billed, if at all, through the resource it belongs to or configures, and it is not out of the model (Google Cloud, Identity and Access Management pricing (read 2026-11-05): "All use of Identity and Access Management API is free of charge") |
| `google_project_iam_member.init_permissions` | NO_CHARGE: google_project_iam_member has no charge of its own (see the billable coverage): there is nothing to price, it is billed, if at all, through the resource it belongs to or configures, and it is not out of the model (Google Cloud, Identity and Access Management pricing (read 2026-11-05): "All use of Identity and Access Management API is free of charge") |
| `google_project_iam_member.server_permissions` | NO_CHARGE: google_project_iam_member has no charge of its own (see the billable coverage): there is nothing to price, it is billed, if at all, through the resource it belongs to or configures, and it is not out of the model (Google Cloud, Identity and Access Management pricing (read 2026-11-05): "All use of Identity and Access Management API is free of charge") |
| `google_service_account.automation` | NO_CHARGE: google_service_account has no charge of its own (see the billable coverage): there is nothing to price, it is billed, if at all, through the resource it belongs to or configures, and it is not out of the model (Google Cloud, Identity and Access Management pricing (read 2026-11-05): "All use of Identity and Access Management API is free of charge") |
| `google_service_account.client` | NO_CHARGE: google_service_account has no charge of its own (see the billable coverage): there is nothing to price, it is billed, if at all, through the resource it belongs to or configures, and it is not out of the model (Google Cloud, Identity and Access Management pricing (read 2026-11-05): "All use of Identity and Access Management API is free of charge") |
| `google_service_account.init` | NO_CHARGE: google_service_account has no charge of its own (see the billable coverage): there is nothing to price, it is billed, if at all, through the resource it belongs to or configures, and it is not out of the model (Google Cloud, Identity and Access Management pricing (read 2026-11-05): "All use of Identity and Access Management API is free of charge") |
| `google_service_account.server` | NO_CHARGE: google_service_account has no charge of its own (see the billable coverage): there is nothing to price, it is billed, if at all, through the resource it belongs to or configures, and it is not out of the model (Google Cloud, Identity and Access Management pricing (read 2026-11-05): "All use of Identity and Access Management API is free of charge") |
| `random_id.suffix` | NO_CHARGE: random_id is a Terraform helper: it creates nothing in a cloud, so there is no resource to bill and nothing to price, and it is not out of the model |
| `random_password.database_user_password` | NO_CHARGE: random_password is a Terraform helper: it creates nothing in a cloud, so there is no resource to bill and nothing to price, and it is not out of the model |
| `random_password.django_admin_password` | NO_CHARGE: random_password is a Terraform helper: it creates nothing in a cloud, so there is no resource to bill and nothing to price, and it is not out of the model |
| `random_password.django_secret_key` | NO_CHARGE: random_password is a Terraform helper: it creates nothing in a cloud, so there is no resource to bill and nothing to price, and it is not out of the model |
| `time_sleep.init_permissions_propagation` | NO_CHARGE: time_sleep is a Terraform helper: it creates nothing in a cloud, so there is no resource to bill and nothing to price, and it is not out of the model |

## Assumptions

No assumption file was given: nothing the source leaves open was chosen.

## The STACKIT list prices

| Item | Value |
|---|---|
| Source | https://pim.api.stackit.cloud/v2/skus?pageSize=100&language=en |
| Retrieved (UTC) | 2026-10-26T18:27:45Z |
| Snapshot sha256 | `94244fec5b573614dcff15f79238ce4a0e60cf197768be287e45092d7e1e61ca` |
| SKUs in the snapshot | 1134 |
| Currency | EUR |
| Price basis | net list price |
| Region looked at | eu01 |
| Price list PDF checked against | not recorded |
| Terms of reuse of the price data | reuse terms not found (U1) |

| State | Resources | Meaning |
|---|---|---|
| Priced | 3 | A tested rule joins the resource to one SKU of the public price list. |
| Unpriced | 0 | The draft names a key the rules know, and the public price list has no price for it. |
| Not assessed | 2 | No tested join exists for the kind of resource, the draft leaves the key to a person, the block is a comment, or more than one SKU matches. |
| With a row | 5 | The drafted resources of a kind the price rules list, written as a resource: the sum of the three states above. |
| Written only as a comment | 0 | Blocks of a kind the price rules list that the draft writes only as a comment. They have a row (NOT_APPLIED_BY_DRAFT in financial/priced-resources.csv), create nothing and are in none of the numbers above. |

5 drafted resources of a kind the price rules do not list have no row, and nothing is stated about their cost. 0 resources have a row and no unit of the estate leads to them.

## What these figures are, and are not

- Only EC2 instances (aws_instance), EBS volumes (aws_ebs_volume and the root and block devices of an instance), RDS for PostgreSQL instances (aws_db_instance: instance hours, allocated storage, provisioned iops, gp3 throughput), Amazon Aurora (aws_rds_cluster_instance: the instance hours; aws_rds_cluster: the consumed storage and the I/O requests with their price and no quantity) the network families (aws_nat_gateway, aws_lb, aws_eip and the public address an instance asks for, aws_route53_zone, aws_internet_gateway: see the line on the network families below) and the managed-service families (aws_ecs_service on Fargate, aws_mq_broker, aws_elasticache_replication_group and aws_elasticache_cluster, aws_opensearch_domain, aws_dynamodb_table: see the line on them below), the control plane of an Amazon EKS cluster (aws_eks_cluster), the nodes of its managed node groups (aws_eks_node_group) and the storage of S3 buckets and EFS file systems (aws_s3_bucket, aws_efs_file_system: see the line on them below) have lines on the source side, and only STACKIT servers (each with its boot volume), volumes, PostgreSQL Flex instances (flavor, storage class, storage capacity), public IPs, load balancers, DNS zones, RabbitMQ, Valkey, OpenSearch and MariaDB instances (their plan), MongoDB Flex instances (their flavor), SKE clusters (the cluster hour and each node pool), KMS keys, Secrets Manager and Logs instances on the target side; the other drafted resources have a line that says they have no quantity rule, and every other source resource has no line and is listed in the out-of-model group.
- The network families have a line on each side, never a total over a partial set. NAT gateway: the hour of a zonal public NAT gateway is priced and the data it processes has the per-GB price and no quantity; the STACKIT price list holds no SKU for a NAT gateway or for outbound address translation, so its target line is PRICE_NOT_FOUND (a service the list does not price is not free). Load balancer: the hour of an Application or Network Load Balancer is priced and its capacity units have the price and no quantity; the target line is the hour of the plan (plan_id; a Network Load Balancer that states none is read as the default p10 the provider documents). Public IPv4 address: the hour of an Elastic IP, and of the address an instance asks for with associate_public_ip_address = true (not an address its subnet or launch template decides), against the hour of a stackit_public_ip. DNS: the month of a hosted zone (the first tier of the Route 53 price; the tier is the account's) and its queries (no quantity); the STACKIT list prices a zone by the number of records it may hold, which the draft does not state, so its target line is AMBIGUOUS. Data transfer out: the per-GB price of the first tier (every tier is named on the line) on the line of the internet gateway and no quantity; the STACKIT list holds no SKU for it, so its target line is PRICE_NOT_FOUND. A quantity that is a measurement of use (GB, capacity unit hours, queries) is never in a Terraform source and is never made up: such a line has its price and no amount. The prices are the On-Demand rows of the AmazonEC2 (NAT gateway, load balancers), AmazonVPC (public IPv4), AWSDataTransfer and AmazonRoute53 offers of the price cache, which `stacktoit prices refresh --provider aws --region R` fetches (`--offer` names one); a line whose offer the cache does not hold names the offer and the command.
- The managed-service families are priced from the On-Demand rows of the AmazonECS (Fargate vCPU and GB hours: the cpu and memory of the task definition times the desired count, which is never taken as zero when it is not stated), AmazonMQ (broker hour by engine, instance type and deployment mode; its storage has the price and no quantity), AmazonElastiCache (node hour by engine and node type times the nodes of a replication group), AmazonES (data and dedicated master node hours, EBS GB-month) and AmazonDynamoDB (provisioned read and write capacity unit hours when the table states them, at the rate beyond the free first tier, which is the whole account's; request units and storage have the price and no quantity) offers, which `stacktoit prices refresh --provider aws --region R` fetches (`--offer` names one); Fargate Spot, ECS on EC2 capacity, Windows tasks, global datastores and non-standard table classes are out of the model. The control plane of an Amazon EKS cluster is the cluster hour of the AmazonEKS offer (the standard-support hour: a cluster of a Kubernetes version past standard support is billed the extended-support hour in addition, which is not in the line, and the line says so; a local cluster on AWS Outposts and a Provisioned Control Plane tier are out of the model; the management fee of EKS Auto Mode is said, not computed). A managed node group costs nothing of its own (Amazon EKS User Guide, Managed node groups): its line is the EC2 hour of the first of its instance_types, or of its launch template, or the t3.medium Amazon EKS uses when none is stated, times its desired_size, with the operating system, tenancy and purchasing option rules of an instance (a Spot or Windows node group is not priced as On-Demand Linux) and the EBS volumes its launch template maps as lines of their own; the root volume of the nodes is not in it. The storage of an S3 bucket (S3 Standard, tiered by the size stored in a month) and of an EFS file system (Standard, or One Zone when availability_zone_name is stated) has its price and no quantity, because the data held is a measurement of use that no Terraform source states: the line names the entry of the assumption file that would price it (variable volume_size, unit GB), and the other storage classes, the requests, the transfer and the throughput are not in it. On the target side a RabbitMQ, Valkey (Key Value Store), OpenSearch or MariaDB instance is the hour of the SKU of its plan_name (the SKU is named by the plan, INFERRED from the names of the list, and its nodes and disk are checked against the list's attributes); a plan the draft leaves to a person is TARGET_NOT_CHOSEN. An SKE cluster is the cluster hour, and each node pool it states is a line of its own: the server flavor hours of its machine_type (the join of a server) times its nodes, the range between its minimum and its maximum when they differ, an unknown quantity with the price when the draft states either as a variable, and TARGET_NOT_CHOSEN when the machine type is a variable; the boot volume of each node is not in the line, and the machines of a pool are never set against the source lines of the nodes of an EKS node group (a unit of its own) or of an ECS cluster's capacity, so a pool is a target-only line (see below); the cluster hour of an SKE cluster stands against the control plane hour of an EKS cluster, but a unit whose item holds a target-only pool is not computed, so no saving is stated over it. A MongoDB Flex instance is the hour of the SKU MongoDB-Flex-<cpu>.<ram>-<Single\|Replica\|Sharded> of its flavor.cpu, flavor.ram and options.type (INFERRED from the names of the list, and checked against the SKU's own attributes; the rate of a Replica SKU is read as that of the whole instance with its nodes); a flavor a person sets is TARGET_NOT_CHOSEN, a flavor the list has no SKU of is PRICE_NOT_FOUND, its storage and backups are not computed, and because this build prices no DocumentDB cluster on the source side its line is target only (see below). A software KMS key version and a GB of log ingestion have their list price and no quantity; Secrets Manager is AMBIGUOUS between its tiers (the number of secret versions). A priced target line of a family whose source side has no line for the unit (an SKE cluster and its node pools, a MariaDB instance, a MongoDB Flex instance, a RabbitMQ plan against a source with no priced broker) is target only: it is counted in the STACKIT total, listed apart with its amount (target_only on the line and target_only_lines, target_only_min and target_only_max on the total), and kept out of every comparison and every saving, because no source amount stands against it; each comparison states the lines and the amount it leaves out, on both sides.
- The instance hours and the allocated storage of an RDS for PostgreSQL instance are priced from the AmazonRDS offer of the price cache (On-Demand list prices, Single-AZ or Multi-AZ as the source states; `stacktoit prices refresh --provider aws` fetches it with the AmazonEC2 offer); its provisioned IOPS (io1, io2, gp3) and the provisioned throughput of gp3 storage come from the same offer, gp3 only above the performance its allocated storage includes (a baseline of 12,000 IOPS and 500 MiB/s from 400 GiB, nothing more can be provisioned below it: Amazon RDS User Guide, DB instance storage); without that offer the lines are PRICE_SOURCE_ABSENT and the instance is never in the computed subtotal. An Aurora instance (engine aurora-mysql or aurora-postgresql) is the instance hour of its engine, its instance class and the storage configuration of its cluster, from the same offer (rules version 3 of its narrowing): Aurora Standard when the cluster states no storage_type (the provider's documented default), Aurora I/O-Optimized for storage_type = "aurora-iopt1", and both prices open (AMBIGUOUS) when the source does not state it as a fact or the instance's cluster is not a resource of the source; the cluster's consumed storage (a GB-month) and, on Standard, its I/O requests are measurements of use and have their price and no quantity. An Aurora Serverless v2 instance (db.serverless), an instance of a Multi-AZ DB cluster, backup storage beyond the free allocation, Global Database and the Data API are not computed. An offer narrowed before the Aurora rows were kept answers PRICE_SOURCE_ABSENT with the refresh command on each Aurora line. A PostgreSQL Flex Replica flavor is priced once per instance: the list gives its SKU 3 nodes and a higher rate than the Single SKU (1.6 to 2.0 times it, never 3 times), and the rate is read as that of the whole instance (evidence class INFERRED from the price list; each such line says so); how much of its storage is billed (once or per node) the list does not say, so its storage lines have the SKU and no quantity.
- The PostgreSQL Flex storage class premium-perf<n>-stackit is priced as the SKU "Block Storage for PostgreSQL Premium-Performance <n>" per disk and its capacity as "Block Storage for PostgreSQL Premium-Capacity" per GB (evidence class INFERRED from the names of the price list; each such line says so). For a replica flavor the list gives the storage per node and does not say whether the booked size is billed once or for each node, so its disks and gigabytes are the range between the two readings. The IOPS and throughput shown for the class in the technical mapping are the attributes maxIOPerSec and maxTroughInMB of that performance SKU in the price list (the catalogue states none for a PostgreSQL Flex class); whether the class covers what the source provisions is a comparison of those figures, not a statement that the two perform alike.
- The lines fall into three groups: the computed subtotal (only the source units every line of which is priced on both sides, so both subtotals cover the same units), the lines whose price is known and whose quantity is not (the quantity that is needed is named), and what is not computed (a unit of a type out of the model, a unit with no line on one side, or a line without a price), listed by resource and never zero.
- Source prices are the On-Demand list prices of the AWS offer file in the price cache (USD, net, region of the resource); Spot, Reserved, Savings Plans, Dedicated Host, capacity reservation and private prices are never used. The operating system and licence come from the assumption file: the source does not state them.
- The offer file bills an EBS volume per GB-month; this build reads it as GiB-month, the unit a volume is sized in: the Amazon EBS pricing page states "on this page, GB = 1024^3 bytes" (OFFICIAL_DOCUMENTED for that page; applying it to the offer file's unit is INFERRED). The IOPS and throughput of a gp3 volume are priced only above the baseline included in the price of its storage (3,000 IOPS, 125 MiB/s: Amazon EBS User Guide, OFFICIAL_DOCUMENTED), per volume; io2 IOPS are priced in tiers whose edges the offer file carries in descriptions only, and are not priced.
- Target prices are the net EUR list prices of the public STACKIT price list in the price cache (region eu01). A machine type or performance class the draft leaves to a person is TARGET_NOT_CHOSEN; the metro variant of a SKU is never substituted.
- The target capacity price of a volume is the capacity SKU of its performance class's tier (evidence class INFERRED from the structure of the price list).
- One month is the 730 hours of the scenario; a per-month rate is applied as the file gives it. Snapshots, backups, support plans and every other cost of usage, traffic or requests that this build has no line for are not computed.
- A saving is compared only for the same source units on both sides and in one currency (an exchange rate from the assumption file, with its source and date, converts one side).
- Google Cloud source lines are priced from the On-Demand list prices of the Cloud Billing Catalog API in the price cache (USD, net, the region of the resource; `stacktoit prices refresh --provider gcp --region R`, with your own API key in STACKTOIT_GCP_BILLING_API_KEY, fetches them; `--offer` names one catalog). The catalog has no machine-type or disk-type field: each line joins its SKU by the words of the SKU's description and needs exactly one SKU to fit (a join INFERRED from the descriptions, said on each line); no fit is PRICE_NOT_FOUND and more than one is AMBIGUOUS, never a pick.
- What the Google Cloud model prices: google_compute_instance and google_compute_instance_from_template (a predefined or custom machine type as its vCPU hours and its memory hours, a shared-core type as its instance hour; the GPUs, the Local SSD, the boot disk with its Hyperdisk or extreme-disk IOPS and throughput; the external address an access_config asks for), google_compute_instance_group_manager and google_compute_region_instance_group_manager (the instances of the one instance template the group names, between the bounds of the autoscaler that targets it, else target_size), google_compute_disk and google_compute_region_disk, google_compute_address (external), google_sql_database_instance (PostgreSQL, MySQL and SQL Server: vCPUs, memory, storage and, for SQL Server, the edition licence; Enterprise Plus, shared-core and legacy named tiers), google_container_cluster and google_container_node_pool, google_redis_instance, google_storage_bucket (also dual-region), google_compute_router_nat, google_dns_managed_zone, google_pubsub_topic, and the serverless, data, security, network and data-processing services: Cloud Run services and jobs, Cloud Functions, BigQuery, Spanner, Bigtable, Firestore, Filestore, Secret Manager, Cloud KMS, Cloud Logging, Cloud Tasks, Cloud Scheduler, Artifact Registry, Dataproc, Dataflow, Composer, load balancer forwarding rules, Cloud Armor, VPN tunnels and Interconnect (the coverage file of this run lists each line). Every other Google Cloud resource has no line and is listed in the out-of-model group.
- A machine series whose memory per vCPU this build does not read from the documentation, a Cloud SQL tier of another series, a Spanner or Firestore multi-region, a custom dual-region bucket and a Composer 1 environment are out of the model or KEY_NOT_READ with the reason on the line; a forwarding rule is priced as an additional rule, without the minimum charge that covers the first rules of a project. Spot, preemptible, sole-tenant, flex-start and reservation-bound capacity is never priced as On-Demand. A premium operating system image (Windows Server, SQL Server, Red Hat or SUSE Enterprise Linux, Ubuntu Pro) gets a licence line that names the licence and is PRICE_NOT_FOUND, so the instance is never in a computed subtotal without its licence fee; an image the source does not state is read as one with no licence fee and the line says so (an ASSUMPTION).
- No discount is applied: the sustained-use discount of the N1, N2, N2D and C2 families, committed-use discounts, the free tier of the billing account (one zonal or Autopilot GKE cluster, the first gigabytes of Pub/Sub) and negotiated prices are not in a list price. A quantity that is a measurement of use (the data a bucket holds, the data a NAT gateway or a topic moves, the VMs a NAT gateway serves, the requests and the instance time of a Cloud Run service or function, the bytes a BigQuery query scans, the operations of a key, a secret or a database, the log volume, the worker hours of a Dataflow job) is never in a Terraform source: such a line has its price and no quantity, until the assumption file states the use. A node count of a regional GKE cluster that lists no node_locations is not known (the zones GKE chooses are not in the source), so its nodes are not priced.
- A list price is the price of one unit of one SKU. It is not a cost: this block reads no quantity and builds no total; the quantities, amounts and totals of the priced families are in financial/cost-model.json.
- A resource is joined to a SKU only where the draft itself names the machine type, performance class or flavor; where the draft leaves that to a person (a variable), no SKU is named and the resource is NOT_ASSESSED.
- Prices are net list prices of the public STACKIT price list: excluding taxes, with no contract discount, no savings plan and no other currency. A SKU that is not in the public list, a deprecated SKU and the metro variant of a SKU are never used as a price.
- Egress and traffic, support plans, the container registry and every resource of a kind the price rules do not list have no row: nothing is stated about their cost.
- Only the region eu01 is looked at: it is the region of the knowledge-base catalogue the draft takes its flavors from.
- The row of a volume is the per-hour fee of its performance class; the capacity fee of the disk is a separate SKU that depends on the size, and is a line of the cost model, not a row here.
