sap-iac.generate
Summary
Role: Required — the final step. · Reads: specs/tasks.md (+ governance) · Writes: terraform/
Generates complete, validated Terraform HCL by executing each task in dependency order.
When to run it
Last, after sap-iac.design has annotated every task with its target file path.
Inputs and outputs
| Reads | specs/tasks.md (with the file-path annotations from design), and memory/governance.md if present. |
| Writes | Terraform files into terraform/, at the paths design annotated. Also updates specs/tasks.md — each completed task's checkbox is flipped from - [ ] to - [x]. |
Behaviour
Stage filter
At the start of the run, generate asks which stage(s) to generate — Which stage(s) should be generated? (e.g. dev, test, prod — or 'all'). Only tasks whose stage annotation matches the answer are processed; tasks outside the chosen stage(s) are skipped and remain in specs/tasks.md as spec-only, ungenerated entries.
- Runs a full governance validation pass across all six categories before writing any file.
- Generates HCL per task in dependency order and writes each configuration unit with the standard layout —
main.tf,variables.tf,outputs.tf,providers.tf(withrequired_providers), andbackend.tf(default local backend). - Generates BTP-located service instances with the BTP provider, CF-located instances with
cloudfoundry/cloudfoundry, and Kyma resources withhashicorp/kubernetes; entitlement-only services generate only their entitlement assignment. - Emits collected service-instance parameters as
parameters = jsonencode(...). It omits the attribute when the task has no parameters. - Emits an entitlement's explicit
amount, including the calculatedAPPLICATION_RUNTIME/MEMORYamount. Otherwise,quota_required: trueproducesamount = 1; tasks with neither field omitamount. - Generates subaccount-level security resources using the split approach:
btp_subaccount_role_collection_basefor each role collection definition andbtp_subaccount_role_collection_rolefor each individual role assignment. Never emitsbtp_subaccount_role_collection. - Generates
btp_subaccount_trust_configurationwith itsidentity_provider. It emitsoriginonly when task metadata contains an explicitly captured origin andorigin_explicit = true; it never derives an origin from the URL. - For every non-role CF resource scoped to a newly created space, retains its space reference and emits an explicit
depends_onfor every recorded role assignment in that same space. This preservesspace -> roles -> resourcein Terraform's apply graph without affecting organization-scoped, BTP, or other-space resources. - For a CF/Kyma split, emits the
btp/outputs.tfwith the CF API URL (provider::btp::extract_cf_api_url) or Kyma kubeconfig URL (provider::btp::extract_kyma_kubeconfig_url, URL only), plus aterraform.tfvars.examplein the consumingcf//kyma/directory for the manual handover. When a directory-per-stage layer exists, itsoutputs.tfexposes the directory ID for the BTP config'sparent_id. Noterraform_remote_statecoupling is generated. - Emits a
terraform.tfvars.examplein every BTP configuration unit listing the provider-initialization variables (e.g.globalaccount_subdomain). Ifmemory/global-account.mdcontains a non-empty- Subdomain: <value>line, that value is pre-filled; otherwise a sentinel placeholder is used. When the same directory also receives handover variables (e.g. aparent_idfrom a directory-per-stage layer), a single merged file is written. - Runs
terraform init, thenterraform fmt --recursive, andterraform validateon each generated directory; on afmtorvalidatefailure it fixes the failing resource and retries until both pass. - If
terraform initfails it reports the error and does not proceed tofmtorvalidate.
Generation stops before writing on a governance violation
With a governance file present, a violation in any of the six categories stops generate before any file is written, unless - Override: true is set. A metered-service concern is a warning only, but a missing required cost-centre tag stops generation.
Generated files are left uncommitted
generate leaves the generated files as unstaged working-tree changes; it never commits or pushes them unless you explicitly ask.
Example
/sap-iac.generate
generate validates against governance, then writes the HCL for the HR leave-request project into terraform/ using the standard per-unit layout — main.tf, variables.tf, outputs.tf, providers.tf, and backend.tf (default local backend) — and runs terraform init, terraform fmt --recursive, and terraform validate on each generated directory. The provider version constraints in providers.tf are resolved at runtime (via the terraform MCP server, falling back to a WebFetch against the Terraform registry) and written as ~> constraints — never hardcoded. Security resources are emitted as btp_subaccount_role_collection_base, btp_subaccount_role_collection_role, and btp_subaccount_trust_configuration blocks; the latter omits origin unless it was explicitly captured. When a specs/connectivity.md was produced, it also emits btp_subaccount_destination_generic and btp_subaccount_destination_certificate resources. When it finishes you can review and apply the result yourself:
cd terraform/btp
terraform init
terraform plan
Related
- Requires
sap-iac.design. - For applying the output, see the usage walkthrough.