Question
terraform/environments/staging/azure does not plan clean, and the drift is destructive. Reconcile it — by import, by adopting config, or by deliberate state rm — until terraform plan reports no changes. Own PR, separate from the CI wiring in #35.
Current plan: 5 to add, 3 to change, 13 to destroy (confirmed identically by a local run and by the CI plan on qBraid/qbraid-infrastructure#623).
1. Nine orphaned qgss resources — the dangerous part
In state, absent from configuration. Their qbook-qunorth config was deleted in e3c51e5 ("chore(staging/azure): remove orphan qbook-qunorth files") without a matching state cleanup:
azurerm_resource_group.qgss azurerm_virtual_network.qgss
azurerm_container_registry.qgss azurerm_subnet.qgss_aks
azurerm_nat_gateway.qgss azurerm_subnet_nat_gateway_association.qgss_aks
azurerm_public_ip.qgss_nat azurerm_nat_gateway_public_ip_association.qgss
azurerm_role_assignment.qgss_aks_acr_pull
The resource group qbraid-staging-qgss is live and holds more than state knows about:
| Resource |
In state? |
qbraidstagingqgss (ACR) |
yes |
vnet-qgss-staging, ng-qgss-staging, pip-qgss-nat |
yes |
qbraid-staging-qgss (AKS cluster) |
no |
qgss-staging.private.postgres.database.azure.com (+ vnet link) |
no |
qbraidcentralususers (storage) |
no |
Destroying azurerm_resource_group.qgss therefore takes the AKS cluster and Postgres with it, neither of which Terraform is tracking.
The decision this ticket has to make: adopt or disown. Either re-adopt the stack into a working directory that actually configures it (terraform/providers/azure/services/qbook-qunorth/ already exists and may be its intended home — check whether it manages these resources in its own state before importing anywhere), or state rm all nine so they become deliberately unmanaged. Adopting is the better outcome if the stack is still in use; importing the untracked AKS/Postgres/storage would then be part of reaching zero diff.
2. Defender pricing plans
Four azurerm_security_center_subscription_pricing resources want replacement because a subplan argument is newly set, e.g.:
+ subplan = "PerSubscription" # forces replacement
~ tier = "Free" -> "Standard"
for arm (PerSubscription), key_vault (PerKeyVault), servers (P2), storage (DefenderForStorageV2); ai, cloud_posture, containers update in place. Confirm the intended tiers — several are live at Free while config asks for Standard, which has a cost implication.
3. Sentinel
azurerm_sentinel_log_analytics_workspace_onboarding.staging wants creating.
Why this blocks #35
#35 enables auto_apply: true for staging-azure, and the destructive-change guard only runs when auto_apply == 'false' (.github/actions/iac-destructive-guard/action.yml:63-65). Staging applies are therefore completely unguarded against destroys: merging #35 before this is fixed means the next push touching staging/azure destroys the qgss stack with no approval gate.
#35's own acceptance criterion — "validate by applying the existing staging Azure config unchanged" — is unreachable until this lands.
Done when
terraform plan in terraform/environments/staging/azure reports no changes.
- No live resource was destroyed to get there.
- The adopt-or-disown decision for the qgss stack is written down.
- qBraid/qbraid-infrastructure#623 can be taken out of draft and merged.
Question
terraform/environments/staging/azuredoes not plan clean, and the drift is destructive. Reconcile it — by import, by adopting config, or by deliberatestate rm— untilterraform planreports no changes. Own PR, separate from the CI wiring in #35.Current plan:
5 to add, 3 to change, 13 to destroy(confirmed identically by a local run and by the CI plan on qBraid/qbraid-infrastructure#623).1. Nine orphaned
qgssresources — the dangerous partIn state, absent from configuration. Their
qbook-qunorthconfig was deleted ine3c51e5("chore(staging/azure): remove orphan qbook-qunorth files") without a matching state cleanup:The resource group
qbraid-staging-qgssis live and holds more than state knows about:qbraidstagingqgss(ACR)vnet-qgss-staging,ng-qgss-staging,pip-qgss-natqbraid-staging-qgss(AKS cluster)qgss-staging.private.postgres.database.azure.com(+ vnet link)qbraidcentralususers(storage)Destroying
azurerm_resource_group.qgsstherefore takes the AKS cluster and Postgres with it, neither of which Terraform is tracking.The decision this ticket has to make: adopt or disown. Either re-adopt the stack into a working directory that actually configures it (
terraform/providers/azure/services/qbook-qunorth/already exists and may be its intended home — check whether it manages these resources in its own state before importing anywhere), orstate rmall nine so they become deliberately unmanaged. Adopting is the better outcome if the stack is still in use; importing the untracked AKS/Postgres/storage would then be part of reaching zero diff.2. Defender pricing plans
Four
azurerm_security_center_subscription_pricingresources want replacement because asubplanargument is newly set, e.g.:for
arm(PerSubscription),key_vault(PerKeyVault),servers(P2),storage(DefenderForStorageV2);ai,cloud_posture,containersupdate in place. Confirm the intended tiers — several are live atFreewhile config asks forStandard, which has a cost implication.3. Sentinel
azurerm_sentinel_log_analytics_workspace_onboarding.stagingwants creating.Why this blocks #35
#35 enables
auto_apply: trueforstaging-azure, and the destructive-change guard only runs whenauto_apply == 'false'(.github/actions/iac-destructive-guard/action.yml:63-65). Staging applies are therefore completely unguarded against destroys: merging #35 before this is fixed means the next push touchingstaging/azuredestroys the qgss stack with no approval gate.#35's own acceptance criterion — "validate by applying the existing staging Azure config unchanged" — is unreachable until this lands.
Done when
terraform planinterraform/environments/staging/azurereports no changes.