pez-infra/.github/workflows/_deploy-core.yml
Rasmus Wejlgaard a218acac34 ci: extract shared SOPS/tofu steps into composite actions
The SOPS install + version, the decrypt loop, the OpenTofu version, and
the Backblaze backend-credential extraction were copy-pasted across
terraform.yml (twice), validate-terraform.yml, and _deploy-core.yml.
A version bump meant editing the same string in up to four places and
was easy to do partially.

Pull them into three local composite actions so each is defined once:
  - setup-tofu          (pins OpenTofu version)
  - sops-decrypt        (installs SOPS, decrypts *.enc.* in place)
  - tofu-backend-creds  (exports Backblaze S3 creds to GITHUB_ENV)

Behaviour is unchanged; sops-decrypt also matches *.enc.env everywhere
(previously only _deploy-core did), which is a no-op in terraform/.
2026-06-18 20:23:35 +01:00

91 lines
2.5 KiB
YAML

name: Deploy (core)
on:
workflow_call:
inputs:
host:
required: true
type: string
playbook:
required: true
type: string
dry_run:
required: false
type: boolean
default: false
secrets:
TAILSCALE_CLIENT_ID:
required: true
TAILSCALE_AUDIENCE:
required: true
SSH_PRIVATE_KEY:
required: true
AGE_SECRET_KEY:
required: true
jobs:
deploy:
name: Deploy ${{ inputs.playbook }} → ${{ inputs.host }}
runs-on: ubuntu-latest
environment: production
permissions:
id-token: write
steps:
- uses: actions/checkout@v6
- name: Cache pip packages
uses: actions/cache@v5
with:
path: ~/.cache/pip
key: pip-ansible
- name: Cache Ansible collections
uses: actions/cache@v5
with:
path: ~/.ansible
key: ansible-galaxy-${{ hashFiles('ansible/requirements.yml') }}
- name: Set up Tailscale
uses: tailscale/github-action@v4
with:
oauth-client-id: ${{ secrets.TAILSCALE_CLIENT_ID }}
audience: ${{ secrets.TAILSCALE_AUDIENCE }}
tags: tag:ci
- name: Set up SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
HOST_IP=$(grep "^${{ inputs.host }}[[:space:]]" ansible/inventory/hosts.ini | grep -o 'ansible_host=[^ ]*' | cut -d= -f2)
if [ -n "$HOST_IP" ]; then
ssh-keyscan -H "$HOST_IP" >> ~/.ssh/known_hosts 2>/dev/null || true
fi
- name: Install Ansible
run: pip install ansible
- name: Install Ansible collections
run: ansible-galaxy install -r ansible/requirements.yml
- name: Decrypt secrets
uses: ./.github/actions/sops-decrypt
with:
age-key: ${{ secrets.AGE_SECRET_KEY }}
- name: Run playbook
working-directory: ansible/
env:
ANSIBLE_HOST_KEY_CHECKING: "false"
run: |
PLAYBOOK="${{ inputs.playbook }}"
PLAYBOOK="${PLAYBOOK#playbooks/}"
PLAYBOOK="${PLAYBOOK%.yml}.yml"
if [ "$PLAYBOOK" != "deploy.yml" ]; then
PLAYBOOK="playbooks/$PLAYBOOK"
fi
ARGS="--limit ${{ inputs.host }}"
if [ "${{ inputs.dry_run }}" = "true" ]; then
ARGS="$ARGS --check --diff"
fi
ansible-playbook "$PLAYBOOK" $ARGS