# tfe-bootstrapper

This module bootstraps Terraform Cloud to create workspaces needed for Okta and Azure

## Backfilling the Okta variable set to existing app workspaces

This module now attaches the existing `OktaClientVariableSet` (the same variable set
already attached to `okta-client` workspaces — see `app/main.tf`,
`attach_external_okta_credentials`) to "app" (API-service) workspaces as well, so the
`okta` provider can self-configure for `external-identity`'s native Okta data sources
(forge#845). No new variable set or `saif-utilities` change was needed for this — it
reuses what already exists.

Merging this change only changes what happens on the **next** `terraform plan` of a
`bootstrap-*` workspace. It does not retroactively attach the variable set to existing
"app" workspaces that already exist and haven't been re-planned since this ships.
Consumers of `saif-api-service` whose `bootstrap-*` workspace isn't re-triggered would
silently keep missing Okta credentials until something forces a plan.

Two options to backfill, in order of preference:

1. **One-time TFC API bulk trigger.** Script a run against every existing `bootstrap-*`
   workspace (list via the TFC API filtered by project/tag) once this module version is
   published, e.g. `POST /runs` with a JSON:API body whose
   `data.relationships.workspace.data.id` is the target workspace ID and whose
   `data.attributes.message` notes why the run was triggered. Pros: explicit, auditable,
   no lingering behavior change. Cons: one-off script to write and run, and it
   re-applies every bootstrap workspace (broader blast radius than just the Okta attach)
   unless scoped carefully (e.g. `is-destroy: false`, plan-only first).
2. **Mark the variable set `global = true` in TFC.** If `OktaClientVariableSet` is
   switched to global scope, TFC auto-attaches it to all *existing and future* workspaces
   in the org without needing a Terraform-side attach or workspace re-plan at all. Pros:
   zero backfill work, no bulk trigger needed. Cons: over-broad — attaches to every
   workspace in the org (including non-API-service ones that don't need Okta
   credentials, and workspaces outside the External tenant), which conflicts with the
   External-tenant/API-service-only scoping this module implements; would also affect
   `okta-client` workspaces' existing global-scope posture. This needs a conscious
   tradeoff decision with whoever owns the TFC org-level variable-set policy, not
   something to change silently.

Neither option is executed by this module — a human should pick one and run it once,
after this change has shipped to `main` and been consumed by the target projects'
bootstrap workspaces (or immediately, if choosing the `global = true` route).

<!-- BEGIN_TF_DOCS -->
## Providers

| Name | Version |
|------|---------|
| <a name="provider_tfe"></a> [tfe](#provider\_tfe) | >= 0.58.1, < 1.0.0 |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_environments"></a> [additional\_environments](#input\_additional\_environments) | Additional environments to create workspaces for, beyond the standard set<br/>returned by module.names.Environments (Test, QA, UAT, Production). Use this<br/>for non-standard environments like PlatformDev that aren't in the canonical<br/>product environment list. Only honored when var.environment is "" (the<br/>default-fan-out path); ignored when var.environment is set to a single env. | <pre>list(object({<br/>    Name         = string<br/>    ShortName    = string<br/>    Description  = string<br/>    IsProduction = bool<br/>  }))</pre> | `[]` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment to create the resources in. | `string` | `""` | no |
| <a name="input_has_external_auth"></a> [has\_external\_auth](#input\_has\_external\_auth) | Whether or not to create external authentication (Okta) workspaces. | `bool` | `true` | no |
| <a name="input_has_internal_auth"></a> [has\_internal\_auth](#input\_has\_internal\_auth) | Whether or not to create internal authentication (Entra ID) workspaces. | `bool` | `true` | no |
| <a name="input_has_subscriptions"></a> [has\_subscriptions](#input\_has\_subscriptions) | Whether or not to create a subscription workspace. | `bool` | `false` | no |
| <a name="input_has_web_app"></a> [has\_web\_app](#input\_has\_web\_app) | Whether or not to create a web app workspace. | `bool` | `false` | no |
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | The id of the project to create the resources in. | `string` | n/a | yes |

## Outputs

No outputs.

## Resources


- data source.tfe_organization.organization (/terraform-docs/main.tf#1)
- data source.tfe_policy_set.policy_set (/terraform-docs/main.tf#10)
- data source.tfe_project.project (/terraform-docs/main.tf#5)    
<!-- END_TF_DOCS -->

---

[View source on GitHub](https://github.com/saif-corp/forge/blob/main/src/terraform/tfe-bootstrapper/README.md)
