Part of the StackToIT package, published unchanged. A document of a proposal: nothing here is approved or applied.

Executive brief — gcp-candidates/terraform-dynamic-python-webapp/infra

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

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

This brief restates the numbers and the states that workspace.json holds. It scores nothing and recommends no decision: every decision it names is for a named architect, and the draft is a proposal.

  • Migration-ready: NO — 72 critical settings of 16 source resources have manual or refused steps open (65 manual, 2 refused, 5 with no step); 26 steps of the plan cannot be carried out now (24 wait only for a decision, 2 are refused)
  • Progress by kind of step: steps to answer: 24 · changes executable now: 5 · waiting: 47 (10 wait for a value); 2 refused (of 78 steps) — plan steps: a step to answer is a step whose work is to decide, not a record of the decision register; changes executable now include the manual steps a person can start without a decision
  • Source assurance: provider not stated (the source names no provider the knowledge base has a compatibility band for) · OpenTofu validation of the source: not run (lock file) · every required input of the source is in the package
  • Cost: Financial comparison: NOT AVAILABLE — no price source for 5 lines; 6 of 8 STACKIT lines have no price; 13 source resources are outside the model and can carry a charge; priced but outside the comparison (STACKIT, target only, no source line stands against them: 1 line, 72.70 EUR; STACKIT, priced lines of units that are not compared: 1 line, 91.97 EUR); the subtotal of one side is not a comparison and no saving is stated. 2 of 22 lines priced (reasons: 5 no cache · 4 target not chosen · 1 ambiguous · 1 use not stated); while both estates run, per month of overlap: source no figure (no line of its estate is priced), STACKIT 164.67 EUR (priced part) (a one-off item, in no total or comparison) - Verdict: no financial comparison: no billable source resource is priced on both sides; no saving is stated. - Priced: no source subtotal (none of the 14 source lines has an amount); STACKIT: partial 164.67 EUR (2 of 8 lines priced); of it 72.70 EUR target only (1 line the source side has no line to stand against: in the total, in no comparison) - Missing: 20 of 22 lines have no price — 5 no cache: run stacktoit prices refresh · 4 target not chosen: state the choice (target_choice) in the assumption file or as the answer cost.target_choice of the inputs file · 1 ambiguous: the line's reason names what chooses between the prices · 1 use not stated: state the use of one month in the assumption file or as a cost answer of the inputs file where the line names the entry
  • Mappings: 0 of 11 land on GA STACKIT services with every critical setting accounted
  • Mapping confidence: 0 of 11 HIGH
  • Automation eligibility: 0 of 11 units — a unit is automation-eligible when its critical settings are closed; this is not the steps that can run as written; 11 cannot be automated in this build: a provider the build cannot check (11 units), a critical value the draft states only as a placement (3 units), a target resource the provider marks experimental (3 units), a unit left to an architect (3 units), a critical setting STACKIT does not support (1 unit) and a decision whose every option is work a person does by hand (1 unit)
  • Live verification: never applied to STACKIT — no STACKIT plan was run over this draft and no step of the plan has met a live STACKIT project; 0 of 2 STACKIT API steps verified live
  • Source provider: not stated — the source names no provider the knowledge base has a compatibility band for

Summary

Scope. 11 units counted in the totals of gcp-candidates/terraform-dynamic-python-webapp/infra; the draft considered 16 units (11 known-present, 5 decided only when OpenTofu plans): 11 with a generated resource · 4 proposed, switched off · 0 need no resource · 1 left for the architect; package state: Partially executable migration package. Nothing of the draft is applied, and no decision is taken for anyone.

The largest open changes and blockers. No answer has reshaped the draft yet; none of these is made.

  1. Review the account name setting
  2. Map the IAM roles of the service account to STACKIT roles
  3. Decide the resource that the unit depends on

Priced part. 2 of 22 lines priced (source 0 of 14, STACKIT 2 of 8); no source subtotal (none of the 14 source lines has an amount); STACKIT: partial 164.67 EUR (2 of 8 lines priced); of it 72.70 EUR target only (1 line the source side has no line to stand against: in the total, in no comparison). 0 of 20 billable source resources priced on both sides (13 more carry no charge of their own): the brief gives no saving and no comparison. A price is a net list price, never a bill, and a resource without a price is not free.

Open work. Critical settings that need a person to decide: 49. Apart from them, 1 is carried by the draft already (confirm only) and 0 are accepted design changes that nobody decides. Resolved: 12 of 62 critical settings. The rest of this brief lists every item with its owner and the condition that closes it; the Decisions page of the report holds the full register.

First required action. Allow STACKIT's pre-release APIs, which may change or be withdrawn: Pub/Sub v1beta (beta) and Secrets Manager v1 (release status not stated). 3 steps of the plan name this decision and wait for this answer (the steps that come after them are counted in what an answer frees); allowing the calls lets the plan carry them out and makes the migration depend on those APIs. If you say no (record a rejection), the calls are not made: the steps of Pub/Sub and Secrets Manager stay open. Record the answer in the decisions file given with --decisions (decisions-template.yaml); answer each API on its own through the members of the record. (Allow the calls of STACKIT APIs that are not generally available, open input).

Proposed pilot. Run one workload of this estate end to end on a STACKIT sandbox project, with an architect closing the open settings above first; the owner of the migration accepts or rejects this proposal.

Applications

2 groups PROPOSED by StackToIT (nobody has confirmed them, so none is an application yet): 0 Migration-ready · 0 blocked · 0 redesign · 2 not Migration-ready

  • migrate — NOT MIGRATION-READY · PROPOSED: not assessed: google_cloud_run_v2_job.migrate has no compatibility contract (the build writes one only for an ECS service) and no readiness from the plan (only a server, a function or a cluster workload counted in the totals of a run with a plan has one) - Can it move now: 0 of 5 automated steps can run as written (4 more are free of decisions and manual prerequisites and wait for a value; 1 waits for decisions); 3 manual steps wait for decisions. - What blocks it: 2 of the 6 decisions to make hold its steps; the ones that free most: DEC-GEN-CONVERT-API-OPT-IN frees 3 steps of the plan by itself, DEC-GEN-CONVERT-SOURCE-REGION-MAPPING frees 1 step of the plan by itself; together 4 distinct steps of the plan. - How much work: 14 manual steps, 0 data moves. It also reaches 3 units that other groups reach as well: their 33 manual steps and 2 data moves (google_sql_database_instance.postgres, google_storage_bucket.media) are in none of the groups' figures. - To accept: 6 open security decisions (DEC-IAM-GOOGLE-CLOUD-RUN-V2-JOB-MIGRATE, DEC-IAM-GOOGLE-SECRET-MANAGER-SECRET-DJANGO-ADMIN-PASSWORD, DEC-IAM-GOOGLE-SERVICE-ACCOUNT-AUTOMATION, DEC-NET-GOOGLE-CLOUD-RUN-V2-JOB-MIGRATE and 2 more).
  • server — NOT MIGRATION-READY · PROPOSED: not assessed: google_cloud_run_v2_service.server has no compatibility contract (the build writes one only for an ECS service) and no readiness from the plan (only a server, a function or a cluster workload counted in the totals of a run with a plan has one) - Can it move now: 0 of 2 automated steps can run as written (2 more are free of decisions and manual prerequisites and wait for a value); 1 manual step waits for decisions. - What blocks it: 1 of the 6 decisions to make holds its steps; no automated step is among the steps they hold, 1 manual step is; the ones that free most: DEC-GEN-CONVERT-SOURCE-REGION-MAPPING frees 1 step of the plan by itself. - How much work: 10 manual steps, 0 data moves. It also reaches 3 units that other groups reach as well: their 33 manual steps and 2 data moves (google_sql_database_instance.postgres, google_storage_bucket.media) are in none of the groups' figures. - To accept: 4 open security decisions (DEC-IAM-GOOGLE-CLOUD-RUN-V2-SERVICE-SERVER, DEC-IAM-GOOGLE-SERVICE-ACCOUNT-SERVER, DEC-NET-GOOGLE-CLOUD-RUN-V2-SERVICE-SERVER, DEC-SEC-GOOGLE-CLOUD-RUN-V2-SERVICE-SERVER).
  • Not in the figures of any application or group: the units that more than one group reaches have 33 manual steps and 2 data moves (google_sql_database_instance.postgres, google_storage_bucket.media); the units that no application and no group holds have 9 manual steps and 0 data moves. These steps are in the plan and in its totals; the figures of an application or group count only the steps that name its own units.

The state is read from the unit classes and from the application compatibility contracts; it is not a validation, and an application with a workload no contract covers is not ready.

The run

Partially executable migration package · For review only · Not approved.

  • Plan steps: 10 OpenTofu steps without a decision · 0 OpenTofu steps waiting for decisions · 57 manual carry-over · 2 unsupported · 1 units left to the architect for redesign — manual carry-over here includes the cutover, verification and retirement steps; STACKIT API steps, and Terraform steps that no decision can free, are in none of these counts, which the Execution line below states; manual carry-over counts the longest method of each open data-movement choice
  • Source unit fate: 9 Terraform-only · 2 hybrid · 0 API-only · 4 proposed, switched off · 1 manual · 0 no resource (of 16 units the draft considered: 11 known-present, 5 decided only when OpenTofu plans) — what becomes of each unit the draft considered; the five add up to the units considered, and Terraform-only and hybrid together are the units generated
  • Execution: 10 of the 12 automated steps (OpenTofu or a script) are free of decisions and manual prerequisites (2 require a design decision) · 0 can run as written · 10 of those 10 wait for a value (project_id, containers_machine_type, containers_nodes_max, containers_nodes_min and 7 more) · stages of 12 automated steps: 12 in the draft, 10 free of decisions and manual prerequisites, 0 rest on no default to confirm, no opt-in to answer and no value to supply, 0 are approved (every decision and default confirmed in the decisions file, and no value left to supply) · 10 Terraform · 2 API (2 wait for the opt-in) · 0 design inputs · 55 manual migration work (37 settings in 14 review steps) (counting the longest method of each open data-movement choice; 7 steps of the other methods not counted) · 2 lifecycle (cutover/verify/retire) · 2 refused (of 78 plan steps) — what each step of the plan is; the categories add up to the plan's steps
  • Inputs: 0 design inputs wait · 27 open requests (7 block the draft — inputs-template.yaml marks them, 4 are preferences this build cannot apply — inputs-template.yaml, NOT APPLICABLE IN THIS BUILD, says where to set each) — design inputs are steps of the plan; requests are what the run asks the customer, listed one by one when the run is given an inputs file or a project
  • Source units: 11 — known-present migration units; 5 more decided only when OpenTofu plans: 5 present with the defaults of their variables (a variable can change that)
  • Critical open settings: 50 — 49 to decide, 1 confirm only; 12 resolved of the 62 the units state; 22 more are open on 5 units decided when OpenTofu plans, not counted here but listed in the decision register (marked: applies only if) — with them the register has 71 critical settings to decide (49 + 22)
  • Decisions to review: 6 decisions to make (4 plan decisions, 2 plan statements) · 1 default to confirm · 16 units to review (72 critical settings: 71 to decide (22 of them are conditional), 1 confirm only) — a decision to make is a record of an open plan decision, manual action or plan statement; a default to confirm is such a record whose default option the draft carries out (no step waits for it: a person confirms it or changes it); a unit to review is the review record of the critical settings of one unit that the knowledge base cannot decide (one record for each owner role, each setting an item of it); conditional settings are on units decided only when OpenTofu plans (decisions.json)
  • Draft coverage: 11 of 16 units with a generated resource — 4 proposed, switched off · 0 need no resource · 1 left for the architect · 13 variables · the 16 are the 11 source units and 5 conditional units
  • Global draft invariants: 12/12 PASS — 3 of the passes checked nothing; consistency checks over the draft; not target behaviour
  • tofu validate: PASSED — static validation; not target behaviour
  • Architect approval: NOT PROVIDED
  • Safe to apply: NOT ASSERTED

Run status: COMPLETE (report published); source status: RUNTIME TOPOLOGY PARTIAL.

What holds the estate back

  • Review the account name setting (open critical setting): 3 units — REVIEW Owner: Identity Architect. Concerns: google_service_account.automation, google_service_account.client, google_service_account.server. Closes when: A person decides what this finding asks, and records the evidence or the decision. The finding says: The account ID is not visible statically; the STACKIT account is named after the source address. — a variable's default, not a fact.
  • Map the IAM roles of the service account to STACKIT roles (open critical setting): 3 units — REVIEW Owner: Identity Architect. Concerns: google_service_account.automation, google_service_account.client, google_service_account.server. Closes when: A person confirms the value against the target, or the knowledge base gains a rule that decides this setting.
  • Decide the resource that the unit depends on (finding group): 2 units — warning Owner: unassigned (a finding records no owner role). Concerns: google_cloudbuild_trigger.init, google_cloudbuild_trigger.placeholder. This unit names google_firebase_hosting_site.client (google_firebase_hosting_site), whose own decision the target does not carry (it is REDESIGN), and the semantic contract of google_cloudbuild_trigger does not read google_firebase_hosting_site, so what the reference becomes is not assessed.
  • Run unsupported volume (finding group): 2 units — warning Owner: unassigned (a finding records no owner role). Concerns: google_cloud_run_v2_job.migrate, google_cloud_run_v2_service.server. A container mounts a Cloud SQL connection, a Cloud Storage bucket (through Cloud Storage FUSE) or an NFS share. The draft writes no volume for these and holds the pods until a person decides: connect to the migrated database or object store over the network instead of the mount, or mount a share or a volume of the cluster yourself.
  • Decide how each principal with a grant on a secret reaches it on STACKIT (finding group): 2 units — warning Owner: unassigned (a finding records no owner role). Concerns: google_secret_manager_secret.django_admin_password, google_secret_manager_secret.django_settings. The secret has grants for individual principals. Access on STACKIT Secrets Manager is coarser than a Secret Manager grant: a Secrets Manager user is read-only or read-write for the whole secrets engine of its instance, with no scope to one secret or path. Narrower access exists only as role bindings on the instance or on a secret group (a named list of secrets) in the alpha API of the service, and the pinned provider offers them as resources of its experimental IAM feature (stackit_secretsmanager_instance_role_binding_v1 and stackit_secretsmanager_secret_group_role_binding_v1), which its documentation says may change or be removed; the specification does not list the roles a secret group accepts. A grant of one Google principal on one secret therefore cannot be carried one to one: decide per principal whether it gets a user of the whole instance, a role binding on a secret group of the secrets it may read, or a separate Secrets Manager instance.
  • Choose the container image or artifact (open critical setting): 2 units — REVIEW Owner: Platform Architect. Concerns: google_cloud_run_v2_job.migrate, google_cloud_run_v2_service.server. Closes when: A person confirms the executable artifact or image for the STACKIT target: where it is built or pulled from and that the same build runs there.
  • Confirm the region the data stays in (open critical setting): 2 units — REVIEW Concerns: google_cloud_run_v2_job.migrate, google_cloud_run_v2_service.server. Closes when: A person confirms the STACKIT region of the SKE cluster the workload runs on holds the residency the source region gave, since no mapping between Google and STACKIT regions is evidenced.
  • Decide how the secrets are carried (open critical setting): 2 units — REVIEW Owner: Identity Architect. Concerns: google_secret_manager_secret.django_admin_password, google_secret_manager_secret.django_settings. Closes when: A person recreates the secret in the Secrets Manager instance, since its data is not written into the draft, and decides for each IAM member whether it gets a user of the whole instance, a role binding on a secret group, or a separate instance.
  • Provide the values of the secrets (open critical setting): 2 units — REVIEW Owner: Security Architect. Concerns: google_secret_manager_secret.django_admin_password, google_secret_manager_secret.django_settings. Closes when: A person decides where the value comes from, supplies the document and the step has run.
  • Create the Kubernetes Secrets for the Secret Manager references (open critical setting): 2 units — REVIEW Owner: Security Architect. Concerns: google_cloud_run_v2_job.migrate, google_cloud_run_v2_service.server. Closes when: A person creates the Kubernetes Secrets the manifest lists, filled from STACKIT Secrets Manager (for example with an External Secrets Operator).

The full lists are on the Decisions and Architecture pages of index.html.

Source assurance warnings

These are about how well the source was read, not about what blocks the migration; they are listed apart from the blockers and dismiss nothing.

  • Verify the version of the source provider (finding group): 16 units — warning no lock file records the version of registry.terraform.io/hashicorp/google, and the constraint ">= 6, < 8" excludes it (pinned 8.4.0) (stated once for the whole estate, with the units it covers and the rest of the words)

How much was understood

  • Units counted in the totals: 11; decided only when OpenTofu plans: 5; switched off: 0; uncertain facets: 0.
  • Entries of the unit list: 16 (11 units counted in the totals, 5 decided only when OpenTofu plans, 0 switched off).
  • Evidence traces, by kind of entry: active units with a block in the draft: 6 of 10 traced (6 from the lines the draft records for them, not from a typed plan; 4 drafted without a trace); active units with no block in the draft: 0 of 1 traced (nothing to trace); units decided only when OpenTofu plans: 1 of 5 traced (1 from the lines the draft records for them, not from a typed plan). An entry without a trace is not an entry with nothing open; the unit list says for each why it has none.
  • Critical settings: 12 resolved of 62; 50 open.

What people must decide

Decision register: BUILT. 6 decisions to make (4 plan decisions, 2 plan statements) · 1 default to confirm · 16 units to review (72 critical settings: 71 to decide (22 of them are conditional), 1 confirm only); rejected 0, stale 0, entries of the decisions file that match no record 0. The records are in executive/decisions.md and migration/decisions.csv.

What the target would look like

Of the 11 units counted in the totals, 10 units state a STACKIT target and 1 unit states none.

  • STACKIT service account: 3 units
  • STACKIT Secrets Manager: 2 units
  • Kubernetes Job/CronJob on SKE: 1 unit
  • SKE workload (or Cloud Foundry Docker app): 1 unit
  • STACKIT Object Storage: 1 unit
  • STACKIT PostgreSQL Flex: 1 unit
  • STACKIT RabbitMQ: 1 unit

What has and has not been established

What has been established about this draft, row by row, and what has not. Nothing here approves the draft, asserts that it is equivalent to the source, or says it is safe to apply.

RowStateDetail
Source completenessPARTIALsource status RUNTIME_TOPOLOGY_PARTIAL
Draft generationGENERATEDthe draft is in terraform/
StackToIT draft checksPASSED20 checks, none found a violation
Global invariantsPASSED12 of 12 invariants PASS; vacuous, they checked nothing: NO_SECURITY_WIDENING, VARIABLE_IDENTITY_PRESERVED, APPLICATION_READY_IMPLIES_REQUIRED_ENV_SECRETS_DEPENDENCIES
OpenTofu validationPASSEDtofu init -backend=false and tofu validate accepted the draft; tofu 1.13.1
Output schema validationPASSEDverified at publish: every JSON file that has a schema is validated against it (see run_verification in manifest.json)
STACKIT planNOT RUNthis build runs no plan against a STACKIT project
Architect approvalNOT PROVIDEDno review decision is recorded for this run
Semantic equivalenceNOT ASSESSEDthis build has no measure for it
Safe to applyNOT ASSERTEDStackToIT never asserts it

assurance/safety.md states the same rows with their scope and the checks behind them.

Next steps

  • Review the 71 open critical settings: a person decides each (index.html, Decisions page; assurance/critical-semantics.json, critical_semantic_resolution.open). 22 of them belong to units that exist only if a plan-time input holds (critical_semantic_resolution.conditional_open). 1 more is carried by the draft already: confirm only.
  • Review the 4 open plan decisions and 0 manual actions of the draft (index.html, Architecture, Deployment prerequisites). Confirm the 1 default the draft carries out (index.html, Decisions page): no step waits for the answer, a person confirms each or changes it.
  • Review the draft in terraform/: nothing in it is approved, and an architect has to review it before any use.
  • Open index.html in a browser for the unit-by-unit view (offline, nothing is loaded).