Pipeline branch filters and PR bases, Flux GitRepository ref, image automation checkout and push, restore-test, vmtest and bootstrap.sh. Merge right before the master -> main rename. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
162 lines
5.6 KiB
YAML
162 lines
5.6 KiB
YAML
when:
|
|
# Plan only on main (merge) + manual — a push trigger without this gate
|
|
# would run `tofu plan` (which evaluates provider/data-source code) with
|
|
# all proxmox/hetzner/unifi secrets mounted for any pushed branch,
|
|
# including malicious feature-branch .tf.
|
|
- event: push
|
|
branch: main
|
|
path:
|
|
- "opentofu/**"
|
|
- ".woodpecker/deploy-infrastructure.yml"
|
|
- event: deployment
|
|
evaluate: 'CI_PIPELINE_DEPLOY_TARGET == "deploy-infrastructure"'
|
|
|
|
steps:
|
|
- name: validate-secrets
|
|
image: alpine:3.24.2@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6
|
|
environment:
|
|
TF_VAR_proxmox_api_url:
|
|
from_secret: proxmox_api_url
|
|
AWS_ACCESS_KEY_ID:
|
|
from_secret: hetzner_s3_access_key
|
|
commands:
|
|
- |
|
|
if [ -z "$TF_VAR_proxmox_api_url" ]; then echo "Missing proxmox_api_url secret"; exit 1; fi
|
|
if [ -z "$AWS_ACCESS_KEY_ID" ]; then echo "Missing hetzner_s3_access_key secret"; exit 1; fi
|
|
echo "Secrets validated"
|
|
|
|
- name: plan
|
|
image: gitea.renner.uno/gitea_admin/ci-tofu:2026-04-29
|
|
directory: opentofu
|
|
environment:
|
|
TF_IN_AUTOMATION: "true"
|
|
TF_VAR_proxmox_api_url:
|
|
from_secret: proxmox_api_url
|
|
TF_VAR_proxmox_user:
|
|
from_secret: proxmox_user
|
|
TF_VAR_proxmox_token_id:
|
|
from_secret: proxmox_token_id
|
|
TF_VAR_proxmox_token_secret:
|
|
from_secret: proxmox_token_secret
|
|
AWS_ACCESS_KEY_ID:
|
|
from_secret: hetzner_s3_access_key
|
|
AWS_SECRET_ACCESS_KEY:
|
|
from_secret: hetzner_s3_secret_key
|
|
AWS_REGION: "fsn1"
|
|
TF_VAR_unifi_api_key:
|
|
from_secret: unifi_api_key
|
|
TF_VAR_unifi_api_url:
|
|
from_secret: unifi_api_url
|
|
# Hetzner Object Storage S3 keypair (offsite backup buckets).
|
|
# Only consumed once var.enable_hetzner_buckets = true; harmless
|
|
# (unset) until the Console-generated secrets are added.
|
|
TF_VAR_hetzner_s3_access_key:
|
|
from_secret: hetzner_s3_access_key
|
|
TF_VAR_hetzner_s3_secret_key:
|
|
from_secret: hetzner_s3_secret_key
|
|
commands:
|
|
- tofu init -upgrade -backend-config="access_key=$AWS_ACCESS_KEY_ID" -backend-config="secret_key=$AWS_SECRET_ACCESS_KEY"
|
|
- |
|
|
if [ -n "$$TOFU_STATE_RM" ]; then
|
|
for resource in $$TOFU_STATE_RM; do
|
|
tofu state rm "$resource" || true
|
|
done
|
|
fi
|
|
- |
|
|
if [ -n "$$TOFU_IMPORT" ]; then
|
|
echo "$$TOFU_IMPORT" | while read -r line; do
|
|
resource="$${line%% *}"
|
|
id="$${line##* }"
|
|
echo "Importing $resource from $id"
|
|
tofu import "$resource" "$id" || true
|
|
done
|
|
fi
|
|
- |
|
|
TARGET_ARGS=""
|
|
if [ -n "$$TOFU_TARGET" ]; then
|
|
for resource in $$TOFU_TARGET; do
|
|
TARGET_ARGS="$TARGET_ARGS -target=$resource"
|
|
done
|
|
fi
|
|
tofu plan -no-color $TARGET_ARGS
|
|
|
|
- name: apply
|
|
image: gitea.renner.uno/gitea_admin/ci-tofu:2026-04-29
|
|
directory: opentofu
|
|
when:
|
|
- event: deployment
|
|
evaluate: 'TOFU_APPLY == "true"'
|
|
environment:
|
|
TF_IN_AUTOMATION: "true"
|
|
TF_VAR_proxmox_api_url:
|
|
from_secret: proxmox_api_url
|
|
TF_VAR_proxmox_user:
|
|
from_secret: proxmox_user
|
|
TF_VAR_proxmox_token_id:
|
|
from_secret: proxmox_token_id
|
|
TF_VAR_proxmox_token_secret:
|
|
from_secret: proxmox_token_secret
|
|
AWS_ACCESS_KEY_ID:
|
|
from_secret: hetzner_s3_access_key
|
|
AWS_SECRET_ACCESS_KEY:
|
|
from_secret: hetzner_s3_secret_key
|
|
AWS_REGION: "fsn1"
|
|
TF_VAR_unifi_api_key:
|
|
from_secret: unifi_api_key
|
|
TF_VAR_unifi_api_url:
|
|
from_secret: unifi_api_url
|
|
TF_VAR_hetzner_s3_access_key:
|
|
from_secret: hetzner_s3_access_key
|
|
TF_VAR_hetzner_s3_secret_key:
|
|
from_secret: hetzner_s3_secret_key
|
|
SSH_PRIVATE_KEY:
|
|
from_secret: ssh_private_key
|
|
PROXMOX_TOKEN_ID:
|
|
from_secret: proxmox_token_id
|
|
PROXMOX_TOKEN_SECRET:
|
|
from_secret: proxmox_token_secret
|
|
VAULT_PASS:
|
|
from_secret: vault_pass
|
|
ANSIBLE_HOST_KEY_CHECKING: "false"
|
|
ANSIBLE_ROLES_PATH: "../roles:./roles"
|
|
ANSIBLE_FORCE_COLOR: "true"
|
|
commands:
|
|
- mkdir -p ~/.ssh
|
|
- echo "$SSH_PRIVATE_KEY" | base64 -d > ~/.ssh/id_ed25519
|
|
- chmod 600 ~/.ssh/id_ed25519
|
|
- export TF_VAR_ssh_private_key="$(cat ~/.ssh/id_ed25519)"
|
|
- printf "Host *\n\tStrictHostKeyChecking no\n" > ~/.ssh/config
|
|
- echo "$VAULT_PASS" > /tmp/.vault_pass && chmod 600 /tmp/.vault_pass
|
|
- export ANSIBLE_VAULT_PASSWORD_FILE=/tmp/.vault_pass
|
|
- tofu init -upgrade -backend-config="access_key=$AWS_ACCESS_KEY_ID" -backend-config="secret_key=$AWS_SECRET_ACCESS_KEY"
|
|
- |
|
|
if [ -n "$$TOFU_STATE_RM" ]; then
|
|
for resource in $$TOFU_STATE_RM; do
|
|
tofu state rm "$resource" || true
|
|
done
|
|
fi
|
|
- |
|
|
if [ -n "$$TOFU_IMPORT" ]; then
|
|
echo "$$TOFU_IMPORT" | while read -r line; do
|
|
resource="$${line%% *}"
|
|
id="$${line##* }"
|
|
echo "Importing $resource from $id"
|
|
tofu import "$resource" "$id" || true
|
|
done
|
|
fi
|
|
- '[ -n "$$TOFU_TAINT" ] && tofu taint "$$TOFU_TAINT" || true'
|
|
- |
|
|
REPLACE_ARGS=""
|
|
if [ -n "$$TOFU_REPLACE" ]; then
|
|
for resource in $$TOFU_REPLACE; do
|
|
REPLACE_ARGS="$REPLACE_ARGS -replace=$resource"
|
|
done
|
|
fi
|
|
TARGET_ARGS=""
|
|
if [ -n "$$TOFU_TARGET" ]; then
|
|
for resource in $$TOFU_TARGET; do
|
|
TARGET_ARGS="$TARGET_ARGS -target=$resource"
|
|
done
|
|
fi
|
|
tofu apply -auto-approve $REPLACE_ARGS $TARGET_ARGS
|