diff --git a/.woodpecker/migrate-influxdb.yml b/.woodpecker/migrate-influxdb.yml new file mode 100644 index 00000000..d04f5275 --- /dev/null +++ b/.woodpecker/migrate-influxdb.yml @@ -0,0 +1,38 @@ +when: + - event: manual + evaluate: 'PIPELINE == "migrate-influxdb"' + +steps: + - name: backup-and-upload + image: alpine:3.21 + environment: + ANSIBLE_FORCE_COLOR: "true" + ANSIBLE_HOST_KEY_CHECKING: "false" + SSH_PRIVATE_KEY: + from_secret: ssh_private_key + VAULT_PASS: + from_secret: vault_pass + PROXMOX_TOKEN_ID: + from_secret: proxmox_token_id + PROXMOX_TOKEN_SECRET: + from_secret: proxmox_token_secret + # Garage migration target — cluster-independent. Data tarball lands + # at s3://k8s-migration/influxdb/influxdb-backup.tar.gz + S3_ENDPOINT: https://s3.nas-1.renner.uno + S3_BUCKET: k8s-migration/influxdb + S3_ACCESS_KEY: + from_secret: garage_migration_key_id + S3_SECRET_KEY: + from_secret: garage_migration_secret_key + commands: + - apk add --no-cache openssh-client git ansible python3 py3-pip curl + - pip3 install --break-system-packages proxmoxer requests + - ansible-galaxy collection install community.proxmox community.docker + - mkdir -p ~/.ssh + - python3 -c "import base64,os; open(os.path.expanduser('~/.ssh/id_ed25519'),'wb').write(base64.b64decode(os.environ['SSH_PRIVATE_KEY']))" + - chmod 600 ~/.ssh/id_ed25519 + - 'printf "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n" > ~/.ssh/config' + - cd ansible + - echo "$$VAULT_PASS" > .vault_pass && chmod 600 .vault_pass + - export ANSIBLE_VAULT_PASSWORD_FILE=.vault_pass + - ansible-playbook -i inventory/ plays/backup-influxdb.yml -v diff --git a/ansible/plays/backup-influxdb.yml b/ansible/plays/backup-influxdb.yml new file mode 100644 index 00000000..548a02fe --- /dev/null +++ b/ansible/plays/backup-influxdb.yml @@ -0,0 +1,94 @@ +--- +# Backup InfluxDB (VM 108) state to Garage for K8s migration seed. +# Uses `influx backup` (scoped to a single bucket) for an online, no-stop +# snapshot. Output is a backup directory that `influx restore` on the +# K8s side consumes selectively, preserving the K8s InfluxDB's own admin +# bootstrap. +# +# Re-runnable: each run overwrites s3://k8s-migration/influxdb/influxdb-backup.tar.gz +# with the current VM 108 state. Run before each cluster rebuild. +# +# Token: the same read-only `influxdb_token` that the legacy Grafana +# role uses — scoped to the `suedstr28` bucket on VM 108. Loaded from +# the grafana-observability role defaults; single source of truth. +# +# CI-provided env vars: S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY, S3_BUCKET. + +- name: Backup InfluxDB from VM 108 to S3 + hosts: influxdb.srv.renner.uno + become: true + vars_files: + - ../roles/grafana-observability/defaults/main.yml + vars: + s3_endpoint: "{{ lookup('env', 'S3_ENDPOINT') }}" + s3_access_key: "{{ lookup('env', 'S3_ACCESS_KEY') }}" + s3_secret_key: "{{ lookup('env', 'S3_SECRET_KEY') }}" + s3_bucket: "{{ lookup('env', 'S3_BUCKET') }}" + backup_dir: /tmp/influxdb-backup + tasks: + - name: Assert env vars are set + assert: + that: + - s3_endpoint != "" + - s3_access_key != "" + - s3_secret_key != "" + - s3_bucket != "" + - influxdb_token is defined and influxdb_token | length > 0 + + - name: Clean any previous backup directory + file: + path: "{{ backup_dir }}" + state: absent + + - name: Create backup directory + file: + path: "{{ backup_dir }}" + state: directory + mode: "0750" + + - name: Run influx backup (online, scoped to suedstr28/renner) + command: > + /usr/bin/influx backup {{ backup_dir }} + --host http://localhost:8086 + --token {{ influxdb_token }} + --org {{ influxdb_org }} + --bucket {{ influxdb_bucket }} + changed_when: true + no_log: true + + - name: Install mc (MinIO client) + get_url: + url: https://dl.min.io/client/mc/release/linux-amd64/mc + dest: /usr/local/bin/mc + mode: "0755" + force: false + + - name: Configure mc alias for Garage + command: > + /usr/local/bin/mc alias set garage + {{ s3_endpoint }} {{ s3_access_key }} {{ s3_secret_key }} + changed_when: false + no_log: true + + - name: Stream backup directory tarball to S3 + shell: > + set -o pipefail; + tar -cz -C {{ backup_dir | dirname }} {{ backup_dir | basename }} + | /usr/local/bin/mc pipe "garage/{{ s3_bucket }}/influxdb-backup.tar.gz" + args: + executable: /bin/bash + changed_when: true + + - name: List uploaded objects + command: /usr/local/bin/mc ls "garage/{{ s3_bucket }}/" + register: mc_ls + changed_when: false + + - name: Show uploaded objects + debug: + var: mc_ls.stdout_lines + + - name: Clean up backup directory + file: + path: "{{ backup_dir }}" + state: absent