Files
kestra-scripts/hetzner-vm-destroy.yaml
2026-06-26 18:06:22 +02:00

212 lines
6.5 KiB
YAML

id: hetzner-vm-destroy
namespace: hetzner
inputs:
- id: vm_name
type: SELECT
displayName: "VM auswählen"
description: "VM aus der aktuellen Hetzner-Serverliste auswählen. Vorher hetzner-server-available-list ausführen."
expression: "{{ kv('hetzner_server_names') }}"
tasks:
- id: terraform-destroy-plan
type: io.kestra.plugin.terraform.cli.TerraformCLI
containerImage: hashicorp/terraform:latest
env:
AWS_ACCESS_KEY_ID: "{{ secret('AWS_ACCESS_KEY_ID') }}"
AWS_SECRET_ACCESS_KEY: "{{ secret('AWS_SECRET_ACCESS_KEY') }}"
TF_BACKEND_BUCKET: "{{ secret('TF_BACKEND_BUCKET') }}"
TF_BACKEND_ENDPOINT: "{{ secret('TF_BACKEND_ENDPOINT') }}"
TF_VAR_hcloud_token: "{{ secret('HCLOUD_TOKEN') }}"
TF_VAR_ssh_key_name: "{{ secret('SSH_KEY_NAME') }}"
inputFiles:
main.tf: |
terraform {
required_version = ">= 1.5"
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.49"
}
}
backend "s3" {}
}
provider "hcloud" {
token = var.hcloud_token
}
data "hcloud_ssh_key" "default" {
name = var.ssh_key_name
}
resource "hcloud_server" "vm" {
name = var.vm_name
image = "ubuntu-24.04"
server_type = var.server_type
location = var.location
ssh_keys = [data.hcloud_ssh_key.default.id]
public_net {
ipv4_enabled = true
ipv6_enabled = false
}
labels = {
managed_by = "terraform"
team = var.team
}
}
output "vm_ipv4" {
value = hcloud_server.vm.ipv4_address
}
variables.tf: |
variable "hcloud_token" {
type = string
sensitive = true
}
variable "ssh_key_name" {
type = string
}
variable "vm_name" {
type = string
}
variable "server_type" {
type = string
default = "cx23"
}
variable "location" {
type = string
default = "nbg1"
}
variable "team" {
type = string
default = "demo"
}
beforeCommands:
- |
terraform init -reconfigure \
-backend-config="bucket=$TF_BACKEND_BUCKET" \
-backend-config="endpoints={s3=\"$TF_BACKEND_ENDPOINT\"}" \
-backend-config="key=vms/{{ inputs.vm_name }}/terraform.tfstate" \
-backend-config="region=us-east-1" \
-backend-config="skip_requesting_account_id=true" \
-backend-config="skip_credentials_validation=true" \
-backend-config="skip_metadata_api_check=true" \
-backend-config="skip_region_validation=true" \
-backend-config="use_path_style=true"
commands:
- |
set -eo pipefail
terraform plan -destroy -no-color -out=tfdestroyplan \
-var="vm_name={{ inputs.vm_name }}" \
| tee destroy-plan-output.txt
outputFiles:
- tfdestroyplan
- main.tf
- variables.tf
- destroy-plan-output.txt
- id: log-destroy-plan
type: io.kestra.plugin.core.log.Log
message: |
🧨 Terraform Destroy Plan für VM '{{ inputs.vm_name }}':
{{ read(outputs['terraform-destroy-plan'].outputFiles['destroy-plan-output.txt']) }}
──────────────────────────────────────────
→ Bitte genau prüfen und Execution fortsetzen oder abbrechen.
- id: approval-gate
type: io.kestra.plugin.core.flow.Pause
onResume:
- id: approved
type: BOOLEAN
displayName: "VM wirklich löschen?"
description: "True = VM wird gelöscht. False = Execution wird abgebrochen."
defaults: false
- id: destroy-decision
type: io.kestra.plugin.core.flow.If
condition: "{{ outputs['approval-gate'].onResume.approved == true }}"
then:
- id: terraform-destroy-apply
type: io.kestra.plugin.terraform.cli.TerraformCLI
containerImage: hashicorp/terraform:latest
env:
AWS_ACCESS_KEY_ID: "{{ secret('AWS_ACCESS_KEY_ID') }}"
AWS_SECRET_ACCESS_KEY: "{{ secret('AWS_SECRET_ACCESS_KEY') }}"
TF_BACKEND_BUCKET: "{{ secret('TF_BACKEND_BUCKET') }}"
TF_BACKEND_ENDPOINT: "{{ secret('TF_BACKEND_ENDPOINT') }}"
TF_VAR_hcloud_token: "{{ secret('HCLOUD_TOKEN') }}"
TF_VAR_ssh_key_name: "{{ secret('SSH_KEY_NAME') }}"
inputFiles:
main.tf: "{{ outputs['terraform-destroy-plan'].outputFiles['main.tf'] }}"
variables.tf: "{{ outputs['terraform-destroy-plan'].outputFiles['variables.tf'] }}"
tfdestroyplan: "{{ outputs['terraform-destroy-plan'].outputFiles['tfdestroyplan'] }}"
beforeCommands:
- |
terraform init -reconfigure \
-backend-config="bucket=$TF_BACKEND_BUCKET" \
-backend-config="endpoints={s3=\"$TF_BACKEND_ENDPOINT\"}" \
-backend-config="key=vms/{{ inputs.vm_name }}/terraform.tfstate" \
-backend-config="region=us-east-1" \
-backend-config="skip_requesting_account_id=true" \
-backend-config="skip_credentials_validation=true" \
-backend-config="skip_metadata_api_check=true" \
-backend-config="skip_region_validation=true" \
-backend-config="use_path_style=true"
commands:
- |
set -eo pipefail
terraform apply -auto-approve -no-color tfdestroyplan
- id: update_server_inventory_after_destroy
type: io.kestra.plugin.core.flow.Subflow
namespace: hetzner
flowId: hetzner-server-available-list
wait: true
- id: log-result
type: io.kestra.plugin.core.log.Log
message: |
🗑️ VM '{{ inputs.vm_name }}' wurde erfolgreich gelöscht.
Terraform-State wurde über MinIO/S3 aktualisiert:
vms/{{ inputs.vm_name }}/terraform.tfstate
Die Hetzner-Serverliste wurde danach ebenfalls aktualisiert:
inventory/hetzner-server-available.json
inventory/hetzner-server-names.json
Kestra KV:
hetzner_server_names
else:
- id: log-aborted
type: io.kestra.plugin.core.log.Log
message: |
❌ Löschvorgang abgebrochen.
VM '{{ inputs.vm_name }}' wurde nicht gelöscht.