{
  "schema_version": "0.2.1",
  "run_id": "6f8f72b2-1c34-4cfc-8483-344c41245364",
  "source_digest": "sha256:19bfed642d5789ccada81b91d5c36e33175dcafd66dc46b1644ffa105d020000",
  "statement": "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.",
  "file": "financial/cost-model.json",
  "scenario": {
    "id": "STANDARD_730H",
    "label": "the labelled standard month of 730 hours, the same on both sides",
    "hours": "730"
  },
  "price_sources": [
    {
      "side": "SOURCE",
      "provider": "gcp",
      "status": "NOT_AVAILABLE",
      "reason": "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)",
      "region": "global",
      "price_basis": "net list price (On-Demand), catalog PubSub",
      "offer": "PubSub",
      "gap": "NOT_IN_CACHE",
      "rungs_tried": [
        {
          "rung": "PRICE_CACHE",
          "result": "MISSING",
          "words": "the cache at the default location holds no record of it (the cache was last filled 2026-11-02)"
        },
        {
          "rung": "RELEASE_SNAPSHOT",
          "result": "NOT_IMPLEMENTED",
          "words": "none in this build"
        },
        {
          "rung": "AUTO_FETCH",
          "result": "UNAVAILABLE",
          "words": "no program to fetch with: stacktoit-prices was not found next to this binary or on PATH"
        }
      ]
    },
    {
      "side": "SOURCE",
      "provider": "gcp",
      "status": "NOT_AVAILABLE",
      "reason": "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)",
      "region": "global",
      "price_basis": "net list price (On-Demand), catalog SecretManager",
      "offer": "SecretManager",
      "gap": "NOT_IN_CACHE",
      "rungs_tried": [
        {
          "rung": "PRICE_CACHE",
          "result": "MISSING",
          "words": "the cache at the default location holds no record of it (the cache was last filled 2026-11-02)"
        },
        {
          "rung": "RELEASE_SNAPSHOT",
          "result": "NOT_IMPLEMENTED",
          "words": "none in this build"
        },
        {
          "rung": "AUTO_FETCH",
          "result": "UNAVAILABLE",
          "words": "no program to fetch with: stacktoit-prices was not found next to this binary or on PATH"
        }
      ]
    },
    {
      "side": "TARGET",
      "provider": "stackit",
      "status": "USED",
      "retrieved_at": "2026-10-26T18:27:45Z",
      "sha256": "94244fec5b573614dcff15f79238ce4a0e60cf197768be287e45092d7e1e61ca",
      "currency": "EUR",
      "price_basis": "net list price",
      "price_rung": "PRICE_CACHE"
    }
  ],
  "assumptions": {},
  "line_counts": {
    "total": 22,
    "source": 14,
    "target": 8,
    "by_state": {
      "AMBIGUOUS": 1,
      "PRICED": 2,
      "PRICE_NOT_FOUND": 9,
      "PRICE_SOURCE_ABSENT": 5,
      "QUANTITY_UNKNOWN": 1,
      "TARGET_NOT_CHOSEN": 4
    }
  },
  "totals": [
    {
      "scope": "estate",
      "side": "SOURCE",
      "scenario": "STANDARD_730H",
      "state": "NONE",
      "priced_lines": 0,
      "unpriced_lines": 14,
      "unpriced_by_state": {
        "PRICE_NOT_FOUND": 9,
        "PRICE_SOURCE_ABSENT": 5
      },
      "coverage": 7
    },
    {
      "scope": "estate",
      "side": "TARGET",
      "scenario": "STANDARD_730H",
      "currency": "EUR",
      "state": "PARTIAL",
      "min": "164.67",
      "max": "164.67",
      "priced_lines": 2,
      "unpriced_lines": 6,
      "unpriced_by_state": {
        "AMBIGUOUS": 1,
        "QUANTITY_UNKNOWN": 1,
        "TARGET_NOT_CHOSEN": 4
      },
      "coverage": 7,
      "target_only_lines": 1,
      "target_only_min": "72.70",
      "target_only_max": "72.70"
    },
    {
      "scope": "service",
      "key": "containers",
      "side": "TARGET",
      "scenario": "STANDARD_730H",
      "currency": "EUR",
      "state": "PARTIAL",
      "min": "72.70",
      "max": "72.70",
      "priced_lines": 1,
      "unpriced_lines": 1,
      "unpriced_by_state": {
        "TARGET_NOT_CHOSEN": 1
      },
      "coverage": 2,
      "target_only_lines": 1,
      "target_only_min": "72.70",
      "target_only_max": "72.70"
    },
    {
      "scope": "service",
      "key": "database",
      "side": "SOURCE",
      "scenario": "STANDARD_730H",
      "state": "NONE",
      "priced_lines": 0,
      "unpriced_lines": 3,
      "unpriced_by_state": {
        "PRICE_NOT_FOUND": 3
      },
      "coverage": 1
    },
    {
      "scope": "service",
      "key": "database",
      "side": "TARGET",
      "scenario": "STANDARD_730H",
      "currency": "EUR",
      "state": "PARTIAL",
      "min": "91.97",
      "max": "91.97",
      "priced_lines": 1,
      "unpriced_lines": 2,
      "unpriced_by_state": {
        "TARGET_NOT_CHOSEN": 2
      },
      "coverage": 1
    },
    {
      "scope": "service",
      "key": "messaging",
      "side": "SOURCE",
      "scenario": "STANDARD_730H",
      "state": "NONE",
      "priced_lines": 0,
      "unpriced_lines": 1,
      "unpriced_by_state": {
        "PRICE_SOURCE_ABSENT": 1
      },
      "coverage": 1
    },
    {
      "scope": "service",
      "key": "messaging",
      "side": "TARGET",
      "scenario": "STANDARD_730H",
      "state": "NONE",
      "priced_lines": 0,
      "unpriced_lines": 1,
      "unpriced_by_state": {
        "TARGET_NOT_CHOSEN": 1
      },
      "coverage": 1
    },
    {
      "scope": "service",
      "key": "object_storage",
      "side": "SOURCE",
      "scenario": "STANDARD_730H",
      "state": "NONE",
      "priced_lines": 0,
      "unpriced_lines": 1,
      "unpriced_by_state": {
        "PRICE_NOT_FOUND": 1
      },
      "coverage": 1
    },
    {
      "scope": "service",
      "key": "platform",
      "side": "TARGET",
      "scenario": "STANDARD_730H",
      "state": "NONE",
      "priced_lines": 0,
      "unpriced_lines": 1,
      "unpriced_by_state": {
        "AMBIGUOUS": 1
      },
      "coverage": 2
    },
    {
      "scope": "service",
      "key": "secrets",
      "side": "SOURCE",
      "scenario": "STANDARD_730H",
      "state": "NONE",
      "priced_lines": 0,
      "unpriced_lines": 4,
      "unpriced_by_state": {
        "PRICE_SOURCE_ABSENT": 4
      },
      "coverage": 2
    },
    {
      "scope": "service",
      "key": "serverless",
      "side": "SOURCE",
      "scenario": "STANDARD_730H",
      "state": "NONE",
      "priced_lines": 0,
      "unpriced_lines": 5,
      "unpriced_by_state": {
        "PRICE_NOT_FOUND": 5
      },
      "coverage": 2
    },
    {
      "scope": "service",
      "key": "storage",
      "side": "TARGET",
      "scenario": "STANDARD_730H",
      "state": "NONE",
      "priced_lines": 0,
      "unpriced_lines": 1,
      "unpriced_by_state": {
        "QUANTITY_UNKNOWN": 1
      },
      "coverage": 1
    }
  ],
  "comparisons": [
    {
      "scope": "estate",
      "scenario": "STANDARD_730H",
      "comparability": "TARGET_ONLY",
      "source_state": "NONE",
      "target_state": "PARTIAL",
      "reason": "TARGET_ONLY: the source has no priced component",
      "outside": [
        {
          "side": "TARGET",
          "part": "TARGET_ONLY",
          "lines": 1,
          "amount": {
            "currency": "EUR",
            "min": "72.70",
            "max": "72.70"
          }
        }
      ]
    },
    {
      "scope": "service",
      "key": "containers",
      "scenario": "STANDARD_730H",
      "comparability": "TARGET_ONLY",
      "target_state": "PARTIAL",
      "reason": "TARGET_ONLY: there is no source total",
      "outside": [
        {
          "side": "TARGET",
          "part": "TARGET_ONLY",
          "lines": 1,
          "amount": {
            "currency": "EUR",
            "min": "72.70",
            "max": "72.70"
          }
        }
      ]
    },
    {
      "scope": "service",
      "key": "database",
      "scenario": "STANDARD_730H",
      "comparability": "TARGET_ONLY",
      "source_state": "NONE",
      "target_state": "PARTIAL",
      "reason": "TARGET_ONLY: the source has no priced component"
    },
    {
      "scope": "service",
      "key": "messaging",
      "scenario": "STANDARD_730H",
      "comparability": "COMPARABLE",
      "source_state": "NONE",
      "target_state": "NONE",
      "reason": "NONE: neither side has a priced component"
    },
    {
      "scope": "service",
      "key": "object_storage",
      "scenario": "STANDARD_730H",
      "comparability": "SOURCE_ONLY",
      "source_state": "NONE",
      "reason": "SOURCE_ONLY: there is no target total"
    },
    {
      "scope": "service",
      "key": "platform",
      "scenario": "STANDARD_730H",
      "comparability": "TARGET_ONLY",
      "target_state": "NONE",
      "reason": "TARGET_ONLY: there is no source total"
    },
    {
      "scope": "service",
      "key": "secrets",
      "scenario": "STANDARD_730H",
      "comparability": "SOURCE_ONLY",
      "source_state": "NONE",
      "reason": "SOURCE_ONLY: there is no target total"
    },
    {
      "scope": "service",
      "key": "serverless",
      "scenario": "STANDARD_730H",
      "comparability": "SOURCE_ONLY",
      "source_state": "NONE",
      "reason": "SOURCE_ONLY: there is no target total"
    },
    {
      "scope": "service",
      "key": "storage",
      "scenario": "STANDARD_730H",
      "comparability": "TARGET_ONLY",
      "target_state": "NONE",
      "reason": "TARGET_ONLY: there is no source total"
    }
  ],
  "modelled": {
    "resources": 3,
    "source_resources": 33
  },
  "parallel_run": {
    "statement": "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.",
    "sides": [
      {
        "side": "SOURCE",
        "state": "NONE",
        "priced_lines": 0,
        "unpriced_lines": 14
      },
      {
        "side": "TARGET",
        "state": "PARTIAL",
        "currency": "EUR",
        "per_month_min": "164.67",
        "per_month_max": "164.67",
        "priced_lines": 2,
        "unpriced_lines": 6
      }
    ]
  },
  "coverage": {
    "billable": {
      "source_resources": 33,
      "with_price_rule": 7,
      "no_charge_of_its_own": 13,
      "out_of_model": 13,
      "out_of_model_types": [
        {
          "type": "google_cloudbuild_trigger",
          "resources": 3
        },
        {
          "type": "google_secret_manager_secret_iam_binding",
          "resources": 2
        },
        {
          "type": "google_storage_bucket_iam_member",
          "resources": 2
        },
        {
          "type": "google_cloud_run_service_iam_policy",
          "resources": 1
        },
        {
          "type": "google_firebase_hosting_site",
          "resources": 1
        },
        {
          "type": "google_firebase_project",
          "resources": 1
        },
        {
          "type": "google_project_service",
          "resources": 1
        },
        {
          "type": "google_sql_database",
          "resources": 1
        },
        {
          "type": "google_sql_user",
          "resources": 1
        }
      ]
    },
    "price": {
      "lines": 22,
      "found": 2,
      "not_found": 20,
      "not_found_by_state": {
        "AMBIGUOUS": 1,
        "PRICE_NOT_FOUND": 9,
        "PRICE_SOURCE_ABSENT": 5,
        "QUANTITY_UNKNOWN": 1,
        "TARGET_NOT_CHOSEN": 4
      },
      "not_found_by_diagnostic": {
        "AMBIGUOUS": 1,
        "CACHE_MISSING": 5,
        "TARGET_NOT_CHOSEN": 4,
        "USAGE_NOT_STATED": 1
      },
      "by_side": {
        "SOURCE": {
          "lines": 14,
          "found": 0
        },
        "TARGET": {
          "lines": 8,
          "found": 2
        }
      }
    },
    "usage": {
      "priced_lines": 2,
      "quantity_known": 2,
      "quantity_assumed": 0,
      "quantity_unknown": 0
    }
  },
  "unpriced_causes": [
    {
      "diagnostic": "CACHE_MISSING",
      "lines": 5,
      "families": [
        {
          "family": "google_secret_manager_secret",
          "lines": 4
        },
        {
          "family": "google_pubsub_topic",
          "lines": 1
        }
      ],
      "next_action": "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."
    },
    {
      "diagnostic": "TARGET_NOT_CHOSEN",
      "lines": 4,
      "families": [
        {
          "family": "PostgreSQL Flex",
          "lines": 2
        },
        {
          "family": "RabbitMQ",
          "lines": 1
        },
        {
          "family": "SKE",
          "lines": 1
        }
      ],
      "next_action": "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."
    },
    {
      "diagnostic": "AMBIGUOUS",
      "lines": 1,
      "families": [
        {
          "family": "Secrets Manager",
          "lines": 1
        }
      ],
      "next_action": "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.\u003cvariable\u003e 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."
    },
    {
      "diagnostic": "USAGE_NOT_STATED",
      "lines": 1,
      "families": [
        {
          "family": "Object Storage",
          "lines": 1
        }
      ],
      "next_action": "state the use of one month in the assumption file (--assumptions FILE) or as the answer cost.\u003cvariable\u003e 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."
    }
  ],
  "notes": [
    "google_secret_manager_secret_version.django_admin_password: a secret version has no line of its own: the versions of the secret are the use stated on the secret's line",
    "google_secret_manager_secret_version.django_settings: a secret version has no line of its own: the versions of the secret are the use stated on the secret's line",
    "the switched-off proposed modules of the draft (8) are outside this estimate: nothing of them runs until a person switches them on and gives them their values, and their size is one of those values",
    "no application totals: the run was given no applications file (--applications), so no unit belongs to an application"
  ],
  "limits": [
    "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-\u003ccpu\u003e.\u003cram\u003e-\u003cSingle|Replica|Sharded\u003e 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\u003cn\u003e-stackit is priced as the SKU \"Block Storage for PostgreSQL Premium-Performance \u003cn\u003e\" 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."
  ],
  "groups": {
    "statement": "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.",
    "computed": {
      "items": [],
      "totals": [],
      "comparison": {
        "scope": "computed",
        "scenario": "STANDARD_730H",
        "comparability": "NOT_COMPARED",
        "reason": "no source unit is priced on both sides, so there is no computed subtotal to compare",
        "outside": [
          {
            "side": "TARGET",
            "part": "TARGET_ONLY",
            "lines": 1,
            "amount": {
              "currency": "EUR",
              "min": "72.70",
              "max": "72.70"
            }
          },
          {
            "side": "TARGET",
            "part": "NOT_COMPARED",
            "lines": 1,
            "amount": {
              "currency": "EUR",
              "min": "91.97",
              "max": "91.97"
            }
          }
        ]
      }
    },
    "quantity_unknown": [],
    "out_of_model": [
      {
        "source_units": [
          "google_cloud_run_service_iam_policy.server_noauth"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_cloud_run_v2_job.migrate",
          "google_cloud_run_v2_service.server"
        ],
        "lines": [
          {
            "id": "source:google_cloud_run_v2_job.migrate:run_cpu_time",
            "side": "SOURCE",
            "state": "PRICE_NOT_FOUND",
            "quantity_unit": "vCPU-second"
          },
          {
            "id": "source:google_cloud_run_v2_job.migrate:run_memory_time",
            "side": "SOURCE",
            "state": "PRICE_NOT_FOUND",
            "quantity_unit": "GiB-second"
          },
          {
            "id": "source:google_cloud_run_v2_service.server:run_cpu_time",
            "side": "SOURCE",
            "state": "PRICE_NOT_FOUND",
            "quantity_unit": "vCPU-second"
          },
          {
            "id": "source:google_cloud_run_v2_service.server:run_memory_time",
            "side": "SOURCE",
            "state": "PRICE_NOT_FOUND",
            "quantity_unit": "GiB-second"
          },
          {
            "id": "source:google_cloud_run_v2_service.server:run_requests",
            "side": "SOURCE",
            "state": "PRICE_NOT_FOUND",
            "quantity_unit": "request"
          },
          {
            "id": "target:stackit_ske_cluster.containers.node_pool.workloads:node_pool_hours",
            "side": "TARGET",
            "state": "TARGET_NOT_CHOSEN",
            "quantity_unit": "instance"
          },
          {
            "id": "target:stackit_ske_cluster.containers:cluster_hours",
            "side": "TARGET",
            "state": "PRICED",
            "quantity_unit": "cluster",
            "amount": {
              "currency": "EUR",
              "min": "72.70",
              "max": "72.70"
            },
            "target_only": true
          }
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_cloudbuild_trigger.activategcb"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_cloudbuild_trigger.init"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_cloudbuild_trigger.placeholder"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_firebase_hosting_site.client"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_firebase_project.default"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_project_iam_member.automation_permissions"
        ],
        "reasons": [
          "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\")"
        ]
      },
      {
        "source_units": [
          "google_project_iam_member.client_permissions"
        ],
        "reasons": [
          "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\")"
        ]
      },
      {
        "source_units": [
          "google_project_iam_member.init_permissions"
        ],
        "reasons": [
          "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\")"
        ]
      },
      {
        "source_units": [
          "google_project_iam_member.server_permissions"
        ],
        "reasons": [
          "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\")"
        ]
      },
      {
        "source_units": [
          "google_pubsub_topic.faux"
        ],
        "lines": [
          {
            "id": "source:google_pubsub_topic.faux.data:pubsub_data",
            "side": "SOURCE",
            "state": "PRICE_SOURCE_ABSENT",
            "quantity_unit": "GiB"
          },
          {
            "id": "target:stackit_rabbitmq_instance.messaging:service_plan_hours",
            "side": "TARGET",
            "state": "TARGET_NOT_CHOSEN",
            "quantity_unit": "instance"
          }
        ],
        "reasons": [
          "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\""
        ]
      },
      {
        "source_units": [
          "google_secret_manager_secret.django_admin_password",
          "google_secret_manager_secret.django_settings"
        ],
        "lines": [
          {
            "id": "source:google_secret_manager_secret.django_admin_password:secret_access",
            "side": "SOURCE",
            "state": "PRICE_SOURCE_ABSENT",
            "quantity_unit": "operation"
          },
          {
            "id": "source:google_secret_manager_secret.django_admin_password:secret_versions",
            "side": "SOURCE",
            "state": "PRICE_SOURCE_ABSENT",
            "quantity_unit": "version"
          },
          {
            "id": "source:google_secret_manager_secret.django_settings:secret_access",
            "side": "SOURCE",
            "state": "PRICE_SOURCE_ABSENT",
            "quantity_unit": "operation"
          },
          {
            "id": "source:google_secret_manager_secret.django_settings:secret_versions",
            "side": "SOURCE",
            "state": "PRICE_SOURCE_ABSENT",
            "quantity_unit": "version"
          },
          {
            "id": "target:stackit_secretsmanager_instance.migrated_secrets:list_price",
            "side": "TARGET",
            "state": "AMBIGUOUS",
            "quantity_unit": "instance"
          }
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_secret_manager_secret_iam_binding.django_admin_password"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_secret_manager_secret_iam_binding.django_settings"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_service_account.automation"
        ],
        "reasons": [
          "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\")"
        ]
      },
      {
        "source_units": [
          "google_service_account.client"
        ],
        "reasons": [
          "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\")"
        ]
      },
      {
        "source_units": [
          "google_service_account.init"
        ],
        "reasons": [
          "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\")"
        ]
      },
      {
        "source_units": [
          "google_service_account.server"
        ],
        "reasons": [
          "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\")"
        ]
      },
      {
        "source_units": [
          "google_sql_database.database"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_sql_database_instance.postgres"
        ],
        "lines": [
          {
            "id": "source:google_sql_database_instance.postgres.storage:db_storage",
            "side": "SOURCE",
            "state": "PRICE_NOT_FOUND",
            "quantity_unit": "GiB"
          },
          {
            "id": "source:google_sql_database_instance.postgres:sql_ram_hours",
            "side": "SOURCE",
            "state": "PRICE_NOT_FOUND",
            "quantity_unit": "GiB"
          },
          {
            "id": "source:google_sql_database_instance.postgres:sql_vcpu_hours",
            "side": "SOURCE",
            "state": "PRICE_NOT_FOUND",
            "quantity_unit": "vCPU"
          },
          {
            "id": "target:stackit_postgresflex_instance.postgres:db_instance_hours",
            "side": "TARGET",
            "state": "PRICED",
            "quantity_unit": "instance",
            "amount": {
              "currency": "EUR",
              "min": "91.97",
              "max": "91.97"
            }
          },
          {
            "id": "target:stackit_postgresflex_instance.postgres:db_storage",
            "side": "TARGET",
            "state": "TARGET_NOT_CHOSEN",
            "quantity_unit": "GB"
          },
          {
            "id": "target:stackit_postgresflex_instance.postgres:db_storage_perf_class",
            "side": "TARGET",
            "state": "TARGET_NOT_CHOSEN",
            "quantity_unit": "disk"
          }
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_sql_user.django"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_storage_bucket.media"
        ],
        "lines": [
          {
            "id": "source:google_storage_bucket.media.storage:bucket_storage",
            "side": "SOURCE",
            "state": "PRICE_NOT_FOUND",
            "quantity_unit": "GiB"
          },
          {
            "id": "target:stackit_objectstorage_bucket.media:list_price",
            "side": "TARGET",
            "state": "QUANTITY_UNKNOWN",
            "quantity_unit": "instance"
          }
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_storage_bucket_iam_member.automation"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "google_storage_bucket_iam_member.server"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "module.project_services.google_project_service.project_services"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "random_id.suffix"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "random_password.database_user_password"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "random_password.django_admin_password"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "random_password.django_secret_key"
        ],
        "reasons": [
          "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"
        ]
      },
      {
        "source_units": [
          "time_sleep.init_permissions_propagation"
        ],
        "reasons": [
          "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"
        ]
      }
    ]
  },
  "lines": [
    {
      "id": "source:google_cloud_run_v2_job.migrate:run_cpu_time",
      "side": "SOURCE",
      "subject": "google_cloud_run_v2_job.migrate",
      "kind": "run_cpu_time",
      "service_type": "google_cloud_run_v2_job",
      "service": "serverless",
      "region": "unknown",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_cloud_run_v2_job.migrate"
      ],
      "state": "PRICE_NOT_FOUND",
      "reason": "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",
      "supply": {
        "variable": "usage_quantity",
        "unit": "instance-hour",
        "subject": "google_cloud_run_v2_job.migrate.instance_time",
        "value": "the use of one month, in instance-hour"
      },
      "quantity": {
        "form": "NONE",
        "unit": "vCPU-second",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_cloud_run_v2_job.migrate:run_memory_time",
      "side": "SOURCE",
      "subject": "google_cloud_run_v2_job.migrate",
      "kind": "run_memory_time",
      "service_type": "google_cloud_run_v2_job",
      "service": "serverless",
      "region": "unknown",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_cloud_run_v2_job.migrate"
      ],
      "state": "PRICE_NOT_FOUND",
      "reason": "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",
      "supply": {
        "variable": "usage_quantity",
        "unit": "instance-hour",
        "subject": "google_cloud_run_v2_job.migrate.instance_time",
        "value": "the use of one month, in instance-hour"
      },
      "quantity": {
        "form": "NONE",
        "unit": "GiB-second",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_cloud_run_v2_service.server:run_requests",
      "side": "SOURCE",
      "subject": "google_cloud_run_v2_service.server",
      "kind": "run_requests",
      "service_type": "google_cloud_run_v2_service",
      "service": "serverless",
      "region": "unknown",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_cloud_run_v2_service.server"
      ],
      "state": "PRICE_NOT_FOUND",
      "reason": "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",
      "supply": {
        "variable": "usage_quantity",
        "unit": "request",
        "subject": "google_cloud_run_v2_service.server.requests",
        "value": "the use of one month, in request"
      },
      "quantity": {
        "form": "NONE",
        "unit": "request",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_cloud_run_v2_service.server:run_cpu_time",
      "side": "SOURCE",
      "subject": "google_cloud_run_v2_service.server",
      "kind": "run_cpu_time",
      "service_type": "google_cloud_run_v2_service",
      "service": "serverless",
      "region": "unknown",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_cloud_run_v2_service.server"
      ],
      "state": "PRICE_NOT_FOUND",
      "reason": "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",
      "supply": {
        "variable": "usage_quantity",
        "unit": "instance-hour",
        "subject": "google_cloud_run_v2_service.server.instance_time",
        "value": "the use of one month, in instance-hour"
      },
      "quantity": {
        "form": "NONE",
        "unit": "vCPU-second",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_cloud_run_v2_service.server:run_memory_time",
      "side": "SOURCE",
      "subject": "google_cloud_run_v2_service.server",
      "kind": "run_memory_time",
      "service_type": "google_cloud_run_v2_service",
      "service": "serverless",
      "region": "unknown",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_cloud_run_v2_service.server"
      ],
      "state": "PRICE_NOT_FOUND",
      "reason": "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",
      "supply": {
        "variable": "usage_quantity",
        "unit": "instance-hour",
        "subject": "google_cloud_run_v2_service.server.instance_time",
        "value": "the use of one month, in instance-hour"
      },
      "quantity": {
        "form": "NONE",
        "unit": "GiB-second",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_pubsub_topic.faux.data:pubsub_data",
      "side": "SOURCE",
      "subject": "google_pubsub_topic.faux.data",
      "kind": "pubsub_data",
      "service_type": "google_pubsub_topic",
      "service": "messaging",
      "region": "global",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_pubsub_topic.faux"
      ],
      "state": "PRICE_SOURCE_ABSENT",
      "reason": "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",
      "diagnostic": "CACHE_MISSING",
      "supply": {
        "variable": "data_transfer",
        "unit": "GiB",
        "subject": "google_pubsub_topic.faux.data",
        "value": "the use of one month, in GiB"
      },
      "quantity": {
        "form": "NONE",
        "unit": "GiB",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_secret_manager_secret.django_admin_password:secret_versions",
      "side": "SOURCE",
      "subject": "google_secret_manager_secret.django_admin_password",
      "kind": "secret_versions",
      "service_type": "google_secret_manager_secret",
      "service": "secrets",
      "region": "global",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_secret_manager_secret.django_admin_password"
      ],
      "state": "PRICE_SOURCE_ABSENT",
      "reason": "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",
      "diagnostic": "CACHE_MISSING",
      "supply": {
        "variable": "usage_quantity",
        "unit": "version",
        "subject": "google_secret_manager_secret.django_admin_password.versions",
        "value": "the use of one month, in version"
      },
      "quantity": {
        "form": "NONE",
        "unit": "version",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_secret_manager_secret.django_admin_password:secret_access",
      "side": "SOURCE",
      "subject": "google_secret_manager_secret.django_admin_password",
      "kind": "secret_access",
      "service_type": "google_secret_manager_secret",
      "service": "secrets",
      "region": "global",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_secret_manager_secret.django_admin_password"
      ],
      "state": "PRICE_SOURCE_ABSENT",
      "reason": "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",
      "diagnostic": "CACHE_MISSING",
      "supply": {
        "variable": "usage_quantity",
        "unit": "operation",
        "subject": "google_secret_manager_secret.django_admin_password.operations",
        "value": "the use of one month, in operation"
      },
      "quantity": {
        "form": "NONE",
        "unit": "operation",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_secret_manager_secret.django_settings:secret_versions",
      "side": "SOURCE",
      "subject": "google_secret_manager_secret.django_settings",
      "kind": "secret_versions",
      "service_type": "google_secret_manager_secret",
      "service": "secrets",
      "region": "global",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_secret_manager_secret.django_settings"
      ],
      "state": "PRICE_SOURCE_ABSENT",
      "reason": "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",
      "diagnostic": "CACHE_MISSING",
      "supply": {
        "variable": "usage_quantity",
        "unit": "version",
        "subject": "google_secret_manager_secret.django_settings.versions",
        "value": "the use of one month, in version"
      },
      "quantity": {
        "form": "NONE",
        "unit": "version",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_secret_manager_secret.django_settings:secret_access",
      "side": "SOURCE",
      "subject": "google_secret_manager_secret.django_settings",
      "kind": "secret_access",
      "service_type": "google_secret_manager_secret",
      "service": "secrets",
      "region": "global",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_secret_manager_secret.django_settings"
      ],
      "state": "PRICE_SOURCE_ABSENT",
      "reason": "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",
      "diagnostic": "CACHE_MISSING",
      "supply": {
        "variable": "usage_quantity",
        "unit": "operation",
        "subject": "google_secret_manager_secret.django_settings.operations",
        "value": "the use of one month, in operation"
      },
      "quantity": {
        "form": "NONE",
        "unit": "operation",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_sql_database_instance.postgres:sql_vcpu_hours",
      "side": "SOURCE",
      "subject": "google_sql_database_instance.postgres",
      "kind": "sql_vcpu_hours",
      "service_type": "google_sql_database_instance",
      "service": "database",
      "region": "unknown",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_sql_database_instance.postgres"
      ],
      "state": "PRICE_NOT_FOUND",
      "reason": "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",
      "quantity": {
        "form": "VALUE",
        "min": "2",
        "max": "2",
        "unit": "vCPU",
        "run_hours": "730",
        "provenance": {
          "kind": "SOURCE_KNOWN",
          "evidence": "database.tf:25 google_sql_database_instance.postgres count = one -\u003e 1 instance(s); database.tf:33 google_sql_database_instance.postgres settings[0].tier; tier db-custom-2-4096: 2 vCPUs and 4.00 GiB of memory (the tier names them: db-custom-\u003cvCPUs\u003e-\u003cMB\u003e); ASSUMPTION (read from the source, not stated by it): settings.availability_type is not stated; Cloud SQL runs the instance in one zone (ZONAL); scenario STANDARD_730H: 730 h"
        }
      }
    },
    {
      "id": "source:google_sql_database_instance.postgres:sql_ram_hours",
      "side": "SOURCE",
      "subject": "google_sql_database_instance.postgres",
      "kind": "sql_ram_hours",
      "service_type": "google_sql_database_instance",
      "service": "database",
      "region": "unknown",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_sql_database_instance.postgres"
      ],
      "state": "PRICE_NOT_FOUND",
      "reason": "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",
      "quantity": {
        "form": "VALUE",
        "min": "4",
        "max": "4",
        "unit": "GiB",
        "run_hours": "730",
        "provenance": {
          "kind": "SOURCE_KNOWN",
          "evidence": "database.tf:25 google_sql_database_instance.postgres count = one -\u003e 1 instance(s); database.tf:33 google_sql_database_instance.postgres settings[0].tier; tier db-custom-2-4096: 2 vCPUs and 4.00 GiB of memory (the tier names them: db-custom-\u003cvCPUs\u003e-\u003cMB\u003e); ASSUMPTION (read from the source, not stated by it): settings.availability_type is not stated; Cloud SQL runs the instance in one zone (ZONAL); scenario STANDARD_730H: 730 h"
        }
      }
    },
    {
      "id": "source:google_sql_database_instance.postgres.storage:db_storage",
      "side": "SOURCE",
      "subject": "google_sql_database_instance.postgres.storage",
      "kind": "db_storage",
      "service_type": "google_sql_database_instance",
      "service": "database",
      "region": "unknown",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_sql_database_instance.postgres"
      ],
      "state": "PRICE_NOT_FOUND",
      "reason": "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",
      "quantity": {
        "form": "NONE",
        "unit": "GiB",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "source:google_storage_bucket.media.storage:bucket_storage",
      "side": "SOURCE",
      "subject": "google_storage_bucket.media.storage",
      "kind": "bucket_storage",
      "service_type": "google_storage_bucket",
      "service": "object_storage",
      "region": "unknown",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_storage_bucket.media"
      ],
      "state": "PRICE_NOT_FOUND",
      "reason": "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",
      "supply": {
        "variable": "volume_size",
        "unit": "GiB",
        "subject": "google_storage_bucket.media.storage",
        "value": "the use of one month, in GiB"
      },
      "quantity": {
        "form": "NONE",
        "unit": "GiB",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "target:stackit_objectstorage_bucket.media:list_price",
      "side": "TARGET",
      "subject": "stackit_objectstorage_bucket.media",
      "kind": "list_price",
      "service_type": "stackit_objectstorage_bucket",
      "service": "storage",
      "region": "eu01",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_storage_bucket.media"
      ],
      "target_subject": "stackit_objectstorage_bucket.media",
      "state": "QUANTITY_UNKNOWN",
      "reason": "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",
      "diagnostic": "USAGE_NOT_STATED",
      "supply": {
        "variable": "volume_size",
        "unit": "GB",
        "subject": "stackit_objectstorage_bucket.media",
        "value": "the average gigabytes one bucket holds, in GB"
      },
      "quantity": {
        "form": "NONE",
        "unit": "instance",
        "run_hours": "730",
        "provenance": {
          "kind": "UNKNOWN"
        }
      },
      "list_price": {
        "sku": "ST-0010801",
        "name": "Object Storage Premium-EU01",
        "unit_price": "0.00003697772",
        "currency": "EUR",
        "unit": "Gigabyte Hours",
        "unit_billing": "per GB/hour"
      }
    },
    {
      "id": "target:stackit_postgresflex_instance.postgres:db_instance_hours",
      "side": "TARGET",
      "subject": "stackit_postgresflex_instance.postgres",
      "kind": "db_instance_hours",
      "service_type": "stackit_postgresflex_instance",
      "service": "database",
      "region": "eu01",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_sql_database_instance.postgres"
      ],
      "target_subject": "stackit_postgresflex_instance.postgres",
      "state": "PRICED",
      "reason": "list price ST-0025701 0.12598444444 EUR per hour applied to 730 hours",
      "quantity": {
        "form": "VALUE",
        "min": "1",
        "max": "1",
        "unit": "instance",
        "run_hours": "730",
        "provenance": {
          "kind": "SOURCE_KNOWN",
          "evidence": "draft data.tf:18 no count or for_each: one resource; scenario STANDARD_730H: 730 h"
        }
      },
      "price": {
        "record_id": "ST-0025701",
        "sku": "ST-0025701",
        "rate": "0.12598444444",
        "currency": "EUR",
        "unit_of_measure": "Hours (per hour)",
        "quantity_unit": "instance",
        "basis": "PER_HOUR",
        "effective_date": "2026-10-08",
        "snapshot_sha256": "94244fec5b573614dcff15f79238ce4a0e60cf197768be287e45092d7e1e61ca",
        "source": "PUBLIC_LIST"
      },
      "amount": {
        "currency": "EUR",
        "min": "91.97",
        "max": "91.97"
      }
    },
    {
      "id": "target:stackit_postgresflex_instance.postgres:db_storage_perf_class",
      "side": "TARGET",
      "subject": "stackit_postgresflex_instance.postgres",
      "kind": "db_storage_perf_class",
      "service_type": "stackit_postgresflex_instance",
      "service": "database",
      "region": "eu01",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_sql_database_instance.postgres"
      ],
      "target_subject": "stackit_postgresflex_instance.postgres",
      "state": "TARGET_NOT_CHOSEN",
      "reason": "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",
      "diagnostic": "TARGET_NOT_CHOSEN",
      "supply": {
        "variable": "target_choice",
        "subject": "stackit_postgresflex_instance.postgres.storage_class",
        "value": "a storage class such as \"premium-perf6-stackit\""
      },
      "quantity": {
        "form": "VALUE",
        "min": "1",
        "max": "1",
        "unit": "disk",
        "run_hours": "730",
        "provenance": {
          "kind": "SOURCE_KNOWN",
          "evidence": "draft data.tf:18 no count or for_each: one resource; scenario STANDARD_730H: 730 h"
        }
      }
    },
    {
      "id": "target:stackit_postgresflex_instance.postgres:db_storage",
      "side": "TARGET",
      "subject": "stackit_postgresflex_instance.postgres",
      "kind": "db_storage",
      "service_type": "stackit_postgresflex_instance",
      "service": "database",
      "region": "eu01",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_sql_database_instance.postgres"
      ],
      "target_subject": "stackit_postgresflex_instance.postgres",
      "state": "TARGET_NOT_CHOSEN",
      "reason": "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",
      "diagnostic": "TARGET_NOT_CHOSEN",
      "supply": {
        "variable": "target_choice",
        "subject": "stackit_postgresflex_instance.postgres.storage_class",
        "value": "a storage class such as \"premium-perf6-stackit\""
      },
      "quantity": {
        "form": "NONE",
        "unit": "GB",
        "run_hours": "730",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "target:stackit_rabbitmq_instance.messaging:service_plan_hours",
      "side": "TARGET",
      "subject": "stackit_rabbitmq_instance.messaging",
      "kind": "service_plan_hours",
      "service_type": "stackit_rabbitmq_instance",
      "service": "messaging",
      "region": "eu01",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_pubsub_topic.faux"
      ],
      "target_subject": "stackit_rabbitmq_instance.messaging",
      "state": "TARGET_NOT_CHOSEN",
      "reason": "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\"",
      "diagnostic": "TARGET_NOT_CHOSEN",
      "supply": {
        "variable": "target_choice",
        "subject": "stackit_rabbitmq_instance.messaging",
        "value": "a plan of the catalogue such as \"stackit-rabbitmq-2.4.10-single\""
      },
      "quantity": {
        "form": "VALUE",
        "min": "1",
        "max": "1",
        "unit": "instance",
        "run_hours": "730",
        "provenance": {
          "kind": "SOURCE_KNOWN",
          "evidence": "draft messaging.tf:8 no count or for_each: one resource; scenario STANDARD_730H: 730 h"
        }
      }
    },
    {
      "id": "target:stackit_secretsmanager_instance.migrated_secrets:list_price",
      "side": "TARGET",
      "subject": "stackit_secretsmanager_instance.migrated_secrets",
      "kind": "list_price",
      "service_type": "stackit_secretsmanager_instance",
      "service": "platform",
      "region": "eu01",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_secret_manager_secret.django_admin_password",
        "google_secret_manager_secret.django_settings"
      ],
      "target_subject": "stackit_secretsmanager_instance.migrated_secrets",
      "state": "AMBIGUOUS",
      "reason": "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",
      "diagnostic": "AMBIGUOUS",
      "quantity": {
        "form": "NONE",
        "unit": "instance",
        "run_hours": "730",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    },
    {
      "id": "target:stackit_ske_cluster.containers:cluster_hours",
      "side": "TARGET",
      "subject": "stackit_ske_cluster.containers",
      "kind": "cluster_hours",
      "service_type": "stackit_ske_cluster",
      "service": "containers",
      "region": "eu01",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_cloud_run_v2_job.migrate",
        "google_cloud_run_v2_service.server"
      ],
      "target_subject": "stackit_ske_cluster.containers",
      "target_only": true,
      "state": "PRICED",
      "reason": "list price ST-0010701 0.09959511998 EUR per cluster/hour applied to 730 hours; the cluster hour only: the machines of its node pools are servers, and they are not in this line; TARGET ONLY: the source side holds no line of this family for google_cloud_run_v2_job.migrate, google_cloud_run_v2_service.server (the hour of an SKE cluster stands for a control plane: the source side prices one for an Amazon EKS cluster (aws_eks_cluster), and an ECS cluster has no charge of its own (the Fargate hours of a service and the EC2 hours of its capacity are other units of charge)), so no source amount stands against this one: it is counted in the priced part of the STACKIT total and kept out of the comparison, which states what it leaves out",
      "quantity": {
        "form": "VALUE",
        "min": "1",
        "max": "1",
        "unit": "cluster",
        "run_hours": "730",
        "provenance": {
          "kind": "SOURCE_KNOWN",
          "evidence": "draft kubernetes.tf:15 no count or for_each: one resource; scenario STANDARD_730H: 730 h"
        }
      },
      "price": {
        "record_id": "ST-0010701",
        "sku": "ST-0010701",
        "rate": "0.09959511998",
        "currency": "EUR",
        "unit_of_measure": "Hours (per cluster/hour)",
        "quantity_unit": "cluster",
        "basis": "PER_HOUR",
        "effective_date": "2026-10-08",
        "snapshot_sha256": "94244fec5b573614dcff15f79238ce4a0e60cf197768be287e45092d7e1e61ca",
        "source": "PUBLIC_LIST"
      },
      "amount": {
        "currency": "EUR",
        "min": "72.70",
        "max": "72.70"
      }
    },
    {
      "id": "target:stackit_ske_cluster.containers.node_pool.workloads:node_pool_hours",
      "side": "TARGET",
      "subject": "stackit_ske_cluster.containers.node_pool.workloads",
      "kind": "node_pool_hours",
      "service_type": "stackit_ske_cluster",
      "service": "containers",
      "region": "eu01",
      "scenario": "STANDARD_730H",
      "source_units": [
        "google_cloud_run_v2_job.migrate",
        "google_cloud_run_v2_service.server"
      ],
      "target_subject": "stackit_ske_cluster.containers",
      "state": "TARGET_NOT_CHOSEN",
      "reason": "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\"",
      "diagnostic": "TARGET_NOT_CHOSEN",
      "supply": {
        "variable": "target_choice",
        "subject": "stackit_ske_cluster.containers.node_pool.workloads",
        "value": "a server flavor such as \"g2i.4\""
      },
      "quantity": {
        "form": "NONE",
        "unit": "instance",
        "run_hours": "730",
        "provenance": {
          "kind": "UNKNOWN"
        }
      }
    }
  ]
}
