fix(opentofu): remove retired Gitea/Woodpecker LXC state drift (Fixes #199) #232

Merged
k.renner merged 1 commits from fix/issue-199-tofu-state-drift into master 2026-07-14 17:41:09 +00:00
Member

Fixes #199

What this does

Removes the OpenTofu declarations for the retired standalone LXCs that were migrated into the cluster (Phase 2 of kubernetes/apps/MIGRATION-gitea-woodpecker.md: the gitea/woodpecker Services were flipped ExternalName -> ClusterIP and now run as in-cluster StatefulSets/Deployment):

  • delete opentofu/woodpecker_agents.tf (LXC 910/911), opentofu/lxc_231_woodpecker.tf (231), opentofu/lxc_114_gitea_srv_renner_uno.tf (114)
  • backup_jobs.tf: drop VMIDs 114 + 231 and the 910.. agent loop from backed_up_vmids (they were falsely advertised as PBS-protected)
  • locals.tf / variables.tf: remove the now-orphaned woodpecker_agents local and woodpecker_agent_count variable (nothing else referenced them)
  • delete the dead .woodpecker/deploy-woodpecker-agent.yml and .woodpecker/install-woodpecker-server.yml pipelines — their ansible plays (plays/install-woodpecker-{agent,server}.yml) and roles no longer exist, so they can only fail

REQUIRED before merge / any apply: tofu state rm first

These resources are still in the tofu state. If the .tf is removed (this merge) while they remain in state, the next tofu apply (deploy-infrastructure.yml runs an unscoped apply) will destroy-plan them. To decouple state from reality cleanly, run the state removal against the live backend before this merges / before the next apply:

cd opentofu
tofu init -upgrade -backend-config="access_key=..." -backend-config="secret_key=..."
tofu state rm \
  'module.gitea_srv_renner_uno' \
  'module.woodpecker_srv_renner_uno' \
  'module.woodpecker_agents["910"]' \
  'module.woodpecker_agents["911"]'

Notes:

  • The module resource is proxmox_virtual_environment_container.this; removing the whole module address also drops its nested module.dns_records and null_resource.ansible_provision from state, which is what we want since the entire module is going away.
  • tofu state rm accepts all four addresses in one invocation (shown above).
  • Order matters: state-rm must finish before any tofu apply observes the deleted .tf. After both are done, the plan is a clean no-op (nothing in state, nothing in config).
  • Alternative in-pipeline path: deploy-infrastructure.yml already loops over a TOFU_STATE_RM variable (space-separated addresses) before plan/apply. Setting that variable to the four addresses for the run that applies this branch achieves the same ordering in one shot; unset it afterwards.

Owner confirmation needed (blockers)

  1. Are the Proxmox guests actually destroyed? The migration doc's Decommission section (pct destroy 114/231/910/911) is a runbook; the repo can't prove it ran. Please confirm via pct list on neptune (114/911) and jupiter (231/910) that they are gone. If any guest is still live, this needs a different plan.
  2. state rm vs import — this PR assumes you want these dropped from tofu management entirely (they moved to k8s). Confirm that's the intent (vs. re-importing).

Out of scope (flagged for awareness)

  • opentofu/scripts/validate_plan.py still hard-requires a gitea container in the plan, but it is not wired into any pipeline (dead code), so removing gitea won't break CI through it.
  • The migration doc also says to drop the gitea-lxc / gitea-runner ansible roles; the woodpecker roles are already gone. Ansible-role cleanup is a separate change from this tofu-drift fix.

Generated with Claude Code

Fixes #199 ## What this does Removes the OpenTofu declarations for the retired standalone LXCs that were migrated into the cluster (Phase 2 of `kubernetes/apps/MIGRATION-gitea-woodpecker.md`: the `gitea`/`woodpecker` Services were flipped `ExternalName` -> `ClusterIP` and now run as in-cluster StatefulSets/Deployment): - **delete** `opentofu/woodpecker_agents.tf` (LXC 910/911), `opentofu/lxc_231_woodpecker.tf` (231), `opentofu/lxc_114_gitea_srv_renner_uno.tf` (114) - **backup_jobs.tf**: drop VMIDs `114` + `231` and the `910..` agent loop from `backed_up_vmids` (they were falsely advertised as PBS-protected) - **locals.tf / variables.tf**: remove the now-orphaned `woodpecker_agents` local and `woodpecker_agent_count` variable (nothing else referenced them) - **delete** the dead `.woodpecker/deploy-woodpecker-agent.yml` and `.woodpecker/install-woodpecker-server.yml` pipelines — their ansible plays (`plays/install-woodpecker-{agent,server}.yml`) and roles no longer exist, so they can only fail ## REQUIRED before merge / any apply: `tofu state rm` first These resources are still in the tofu state. If the `.tf` is removed (this merge) **while they remain in state**, the next `tofu apply` (`deploy-infrastructure.yml` runs an unscoped apply) will **destroy-plan** them. To decouple state from reality cleanly, run the state removal against the live backend **before** this merges / before the next apply: ```sh cd opentofu tofu init -upgrade -backend-config="access_key=..." -backend-config="secret_key=..." tofu state rm \ 'module.gitea_srv_renner_uno' \ 'module.woodpecker_srv_renner_uno' \ 'module.woodpecker_agents["910"]' \ 'module.woodpecker_agents["911"]' ``` Notes: - The module resource is `proxmox_virtual_environment_container.this`; removing the **whole module address** also drops its nested `module.dns_records` and `null_resource.ansible_provision` from state, which is what we want since the entire module is going away. - `tofu state rm` accepts all four addresses in one invocation (shown above). - **Order matters**: state-rm must finish *before* any `tofu apply` observes the deleted `.tf`. After both are done, the plan is a clean no-op (nothing in state, nothing in config). - Alternative in-pipeline path: `deploy-infrastructure.yml` already loops over a `TOFU_STATE_RM` variable (space-separated addresses) *before* plan/apply. Setting that variable to the four addresses for the run that applies this branch achieves the same ordering in one shot; unset it afterwards. ## Owner confirmation needed (blockers) 1. **Are the Proxmox guests actually destroyed?** The migration doc's Decommission section (`pct destroy 114/231/910/911`) is a runbook; the repo can't prove it ran. Please confirm via `pct list` on neptune (114/911) and jupiter (231/910) that they are gone. If any guest is still live, this needs a different plan. 2. **state rm vs import** — this PR assumes you want these dropped from tofu management entirely (they moved to k8s). Confirm that's the intent (vs. re-importing). ## Out of scope (flagged for awareness) - `opentofu/scripts/validate_plan.py` still hard-requires a `gitea` container in the plan, but it is **not wired into any pipeline** (dead code), so removing gitea won't break CI through it. - The migration doc also says to drop the `gitea-lxc` / `gitea-runner` ansible roles; the woodpecker roles are already gone. Ansible-role cleanup is a separate change from this tofu-drift fix. Generated with Claude Code
claude-bot added 1 commit 2026-07-14 10:09:37 +00:00
fix(opentofu): remove retired Gitea/Woodpecker LXC state drift
ci/woodpecker/push/deploy-infrastructure Pipeline failed
f006497378
gitea (LXC 114), the woodpecker server (231) and the woodpecker agents
(910/911) were migrated into the cluster (Phase 2: Service flipped
ExternalName -> ClusterIP, now in-cluster StatefulSets/Deployment; see
kubernetes/apps/MIGRATION-gitea-woodpecker.md) and the Proxmox guests
decommissioned -- but their OpenTofu declarations were left behind with
onboot/start = true. An unscoped `tofu apply` (deploy-infrastructure.yml)
would attempt to recreate the retired stack, and backup_jobs.tf still
advertised the dead VMIDs as PBS-protected.

- delete opentofu/woodpecker_agents.tf, lxc_231_woodpecker.tf,
  lxc_114_gitea_srv_renner_uno.tf
- drop VMIDs 114/231 and the 910.. agent loop from backup_jobs.tf
- remove the now-orphaned woodpecker_agents local + woodpecker_agent_count
  variable (only those files referenced them)
- delete the dead .woodpecker/deploy-woodpecker-agent.yml and
  install-woodpecker-server.yml pipelines (their ansible plays/roles no
  longer exist)

REQUIRES `tofu state rm` of the four module resources BEFORE this merges
/ any apply runs, otherwise the plan destroy-plans them. See PR body.

Refs #199

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
k.renner merged commit 8ab5282b82 into master 2026-07-14 17:41:09 +00:00
Sign in to join this conversation.