Skip to content

Reconcile staging/azure terraform drift to a zero-diff plan #43

Description

@Kenny-Heitritter

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.

Metadata

Metadata

Labels

wayfinder:taskWayfinder ticket: manual unblocking task

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions