All checks were successful
Terraform Plan / Terraform Plan (push) Successful in 16s
Use terraform plan -refresh=false for destroy workflows so manual NUKE runs do not spend minutes refreshing Proxmox VM state before building the destroy plan.
127 lines
4.1 KiB
YAML
127 lines
4.1 KiB
YAML
name: Terraform Destroy
|
|
run-name: ${{ gitea.actor }} requested Terraform destroy
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
confirm:
|
|
description: "Type NUKE to confirm destroy"
|
|
required: true
|
|
type: string
|
|
target:
|
|
description: "Destroy scope"
|
|
required: true
|
|
default: all
|
|
type: choice
|
|
options:
|
|
- all
|
|
- control-planes
|
|
- workers
|
|
|
|
concurrency:
|
|
group: terraform-global
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
destroy:
|
|
name: "Terraform Destroy"
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Validate confirmation phrase
|
|
run: |
|
|
if [ "${{ inputs.confirm }}" != "NUKE" ]; then
|
|
echo "Confirmation failed. You must type NUKE."
|
|
exit 1
|
|
fi
|
|
|
|
- name: Checkout repository
|
|
uses: https://gitea.com/actions/checkout@v4
|
|
|
|
- name: Create Terraform secret files
|
|
working-directory: terraform
|
|
run: |
|
|
cat > secrets.auto.tfvars << EOF
|
|
pm_api_token_secret = "${{ secrets.PM_API_TOKEN_SECRET }}"
|
|
SSH_KEY_PUBLIC = "$(printf '%s' "${{ secrets.SSH_KEY_PUBLIC }}" | tr -d '\r\n')"
|
|
EOF
|
|
cat > backend.hcl << EOF
|
|
bucket = "${{ secrets.B2_TF_BUCKET }}"
|
|
key = "terraform.tfstate"
|
|
region = "us-east-005"
|
|
endpoints = {
|
|
s3 = "${{ secrets.B2_TF_ENDPOINT }}"
|
|
}
|
|
access_key = "$(printf '%s' "${{ secrets.B2_KEY_ID }}" | tr -d '\r\n')"
|
|
secret_key = "$(printf '%s' "${{ secrets.B2_APPLICATION_KEY }}" | tr -d '\r\n')"
|
|
skip_credentials_validation = true
|
|
skip_metadata_api_check = true
|
|
skip_region_validation = true
|
|
skip_requesting_account_id = true
|
|
use_path_style = true
|
|
EOF
|
|
|
|
- name: Set up Terraform
|
|
uses: hashicorp/setup-terraform@v2
|
|
with:
|
|
terraform_version: 1.6.6
|
|
terraform_wrapper: false
|
|
|
|
- name: Terraform Init
|
|
working-directory: terraform
|
|
run: terraform init -reconfigure -backend-config=backend.hcl
|
|
|
|
- name: Terraform Destroy Plan
|
|
working-directory: terraform
|
|
run: |
|
|
set -euo pipefail
|
|
case "${{ inputs.target }}" in
|
|
all)
|
|
TF_PLAN_CMD="terraform plan -refresh=false -parallelism=1 -destroy -out=tfdestroy"
|
|
;;
|
|
control-planes)
|
|
TF_PLAN_CMD="terraform plan -refresh=false -parallelism=1 -destroy -target=proxmox_vm_qemu.control_planes -out=tfdestroy"
|
|
;;
|
|
workers)
|
|
TF_PLAN_CMD="terraform plan -refresh=false -parallelism=1 -destroy -target=proxmox_vm_qemu.workers -out=tfdestroy"
|
|
;;
|
|
*)
|
|
echo "Invalid destroy target: ${{ inputs.target }}"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
for attempt in 1 2; do
|
|
echo "Terraform destroy plan attempt $attempt/2"
|
|
if timeout 20m sh -c "$TF_PLAN_CMD"; then
|
|
exit 0
|
|
fi
|
|
if [ "$attempt" -eq 1 ]; then
|
|
echo "Destroy plan attempt failed or timed out; retrying in 20s"
|
|
sleep 20
|
|
fi
|
|
done
|
|
|
|
echo "Terraform destroy plan failed after retries"
|
|
exit 1
|
|
|
|
- name: Terraform Destroy Apply
|
|
working-directory: terraform
|
|
run: |
|
|
set +e
|
|
terraform apply -auto-approve tfdestroy 2>&1 | tee destroy-apply.log
|
|
APPLY_EXIT=${PIPESTATUS[0]}
|
|
|
|
if [ "$APPLY_EXIT" -ne 0 ] && [ -f errored.tfstate ] && grep -q "Failed to persist state to backend" destroy-apply.log; then
|
|
echo "Detected backend state write failure after destroy; attempting recovery push..."
|
|
terraform state push errored.tfstate
|
|
PUSH_EXIT=$?
|
|
|
|
if [ "$PUSH_EXIT" -eq 0 ]; then
|
|
echo "Recovered by pushing errored.tfstate to backend."
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
exit "$APPLY_EXIT"
|