diff --git a/.woodpecker/deploy.yaml b/.woodpecker/deploy.yaml index 054a9fc..68cf0df 100644 --- a/.woodpecker/deploy.yaml +++ b/.woodpecker/deploy.yaml @@ -10,14 +10,73 @@ steps: - name: show-deployment-request image: alpine:3.20 + environment: + ZOT_USERNAME: + from_secret: zot_username + ZOT_PASSWORD: + from_secret: zot_password + SOPS_AGE_KEY: + from_secret: sops_age_key + DEPLOY_SSH_KEY: + from_secret: deploy_ssh_key commands: - 'echo " ARTIFACT=$ARTIFACT"' - 'echo " TARGET=$TARGET"' - test -n "$ARTIFACT" || (echo "ERROR - ARTIFACT param missing" && exit 1) - test -n "$TARGET" || (echo "ERROR - TARGET param missing" && exit 1) - test -f "hosts/$TARGET" || (echo "ERROR - unknown host alias $TARGET" && exit 1) - - 'echo "Resolved host alias $TARGET:"' - - cat "hosts/$TARGET" + - . "hosts/$TARGET" + - 'echo "Resolved host alias $TARGET -> $SSH_USER@$SSH_HOST"' + # Tooling: oras (artifact retrieval) and sops (secret decryption). + - apk add --no-cache curl openssh-client + - curl -sL "https://github.com/oras-project/oras/releases/download/v1.3.4/oras_1.3.4_linux_amd64.tar.gz" -o /tmp/oras.tar.gz + - mkdir -p /tmp/oras-install && tar -xzf /tmp/oras.tar.gz -C /tmp/oras-install + - install /tmp/oras-install/oras /usr/local/bin/oras + - curl -sL "https://github.com/getsops/sops/releases/download/v3.13.3/sops-v3.13.3.linux.amd64" -o /usr/local/bin/sops + - chmod +x /usr/local/bin/sops + # Retrieve the exact deployment artifact by digest/tag reference. + - mkdir -p /tmp/deploy-bundle && cd /tmp/deploy-bundle + - oras login "registry.ci.poc.mehl.mx" -u "$ZOT_USERNAME" -p "$ZOT_PASSWORD" + - oras pull "$ARTIFACT" + - test -f compose.yaml || (echo "ERROR - compose.yaml missing from artifact" && exit 1) + - test -f secrets.prod.env || (echo "ERROR - secrets.prod.env missing from artifact" && exit 1) + - test -f release.env || (echo "ERROR - release.env missing from artifact" && exit 1) + # Decrypt the service's secrets transiently, using the deployment age key. + - sops --decrypt secrets.prod.env > /tmp/deploy-bundle/secrets.decrypted.env + - chmod 600 /tmp/deploy-bundle/secrets.decrypted.env + # Set up the SSH key used to reach the target host. + - mkdir -p -m 700 /tmp/ssh + - echo "$DEPLOY_SSH_KEY" > /tmp/ssh/id_deploy + - chmod 600 /tmp/ssh/id_deploy + # Ensure the remote working directory exists, then transfer + # compose.yaml, release.env and the decrypted secrets to the target host. + - >- + ssh -i /tmp/ssh/id_deploy -o StrictHostKeyChecking=accept-new + "$SSH_USER@$SSH_HOST" + "mkdir -p /tmp/poc-deploy" + - >- + scp -i /tmp/ssh/id_deploy -o StrictHostKeyChecking=accept-new + compose.yaml release.env secrets.decrypted.env + "$SSH_USER@$SSH_HOST:/tmp/poc-deploy/" + # Run the deployment on the target host, then remove the plaintext secrets. + - >- + ssh -i /tmp/ssh/id_deploy -o StrictHostKeyChecking=accept-new + "$SSH_USER@$SSH_HOST" ' + set -a; . /tmp/poc-deploy/release.env; set +a; + docker compose --project-directory /tmp/poc-deploy + -f /tmp/poc-deploy/compose.yaml + --env-file /tmp/poc-deploy/secrets.decrypted.env + pull && + docker compose --project-directory /tmp/poc-deploy + -f /tmp/poc-deploy/compose.yaml + --env-file /tmp/poc-deploy/secrets.decrypted.env + up -d --remove-orphans + ' + - >- + ssh -i /tmp/ssh/id_deploy -o StrictHostKeyChecking=accept-new + "$SSH_USER@$SSH_HOST" + "rm -f /tmp/poc-deploy/secrets.decrypted.env" + - echo "Deployment finished." when: event: [deployment, manual]