diff --git a/.forgejo/workflows/deploy.yaml b/.forgejo/workflows/deploy.yaml new file mode 100644 index 0000000..3ded467 --- /dev/null +++ b/.forgejo/workflows/deploy.yaml @@ -0,0 +1,61 @@ +name: deploy + +# main: dry run, then apply ansible/site.yaml to both servers +# other branches: dry run only +# +# Secrets: SSH_DEPLOY_KEY (user deploy on both servers) and +# ANSIBLE_VAULT_PASSWORD (decrypts inventory/group_vars/all/vault.yaml). + +on: + push: + paths: + - 'ansible/**' + - '.forgejo/workflows/deploy.yaml' + workflow_dispatch: + +jobs: + ansible: + runs-on: nix-latest + env: + NIX_CONFIG: | + experimental-features = nix-command flakes + build-users-group = + sandbox = false + # Pinned so CI runs the same Ansible on every run + NIXPKGS: github:NixOS/nixpkgs/0bb2eedc20e4739f29e8045034f2828ad7054f8f + ANSIBLE_HOST_KEY_CHECKING: "True" + ANSIBLE_FORCE_COLOR: "1" + steps: + - name: Prepare container for actions + run: nix-env -iA nixpkgs.nodejs_22 + + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up credentials + env: + SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }} + ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }} + run: | + if [ -z "$SSH_DEPLOY_KEY" ] || [ -z "$ANSIBLE_VAULT_PASSWORD" ]; then + echo "SSH_DEPLOY_KEY and ANSIBLE_VAULT_PASSWORD must be set as repository secrets" >&2 + exit 1 + fi + umask 077 + mkdir -p ~/.ssh + printf '%s\n' "$SSH_DEPLOY_KEY" > ~/.ssh/id_ed25519 + cp ansible/known_hosts ~/.ssh/known_hosts + printf '%s\n' "$ANSIBLE_VAULT_PASSWORD" > ansible/.vault_pass + + - name: Dry run + working-directory: ansible + run: nix shell "$NIXPKGS#ansible" "$NIXPKGS#openssh" -c ansible-playbook -i inventory/ci.yaml site.yaml --check + + - name: Apply + if: github.ref == 'refs/heads/main' + working-directory: ansible + run: nix shell "$NIXPKGS#ansible" "$NIXPKGS#openssh" -c ansible-playbook -i inventory/ci.yaml site.yaml + + - name: Remove credentials + if: always() + run: rm -f ~/.ssh/id_ed25519 ansible/.vault_pass diff --git a/ansible/inventory/ci.yaml b/ansible/inventory/ci.yaml new file mode 100644 index 0000000..3d8d2fa --- /dev/null +++ b/ansible/inventory/ci.yaml @@ -0,0 +1,24 @@ +--- +# Inventory for the Forgejo Actions runner. Jobs run in containers on +# asxpio-services, so asxpio-ops is reached over the VPC. The services +# host itself is reached through asxpio-ops: a container talking to its +# own host arrives from a Docker bridge address, which sshd and the +# firewall both refuse. + +all: + vars: + ansible_user: deploy + ansible_python_interpreter: /usr/bin/python3 + + children: + asxpio: + children: + ops_servers: + hosts: + asxpio-ops: + ansible_host: "{{ vpc_ip }}" + services_servers: + hosts: + asxpio-services: + ansible_host: "{{ vpc_ip }}" + ansible_ssh_common_args: "-o ProxyJump=deploy@{{ asxpio_ops_vpc_ip }}" diff --git a/ansible/known_hosts b/ansible/known_hosts new file mode 100644 index 0000000..ed9c64c --- /dev/null +++ b/ansible/known_hosts @@ -0,0 +1,2 @@ +10.10.0.10,10.20.0.10 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEzuhnXIFERF+slCGpjnQFhaO5iTVqVn9OMbt7jeFOUf +10.10.0.20,10.20.0.20 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDArwdI8bHpQhNnMqz7vOIGJvb5eYE7GahtkbxrNgtvp