diff --git a/.github/workflows/iac-pipeline-infrastructure-monitor-server.yml b/.github/workflows/iac-pipeline-infrastructure-monitor-server.yml new file mode 100644 index 00000000..d99d4f1c --- /dev/null +++ b/.github/workflows/iac-pipeline-infrastructure-monitor-server.yml @@ -0,0 +1,141 @@ +name: Provision Monitor Server Infrastructure + +on: + workflow_dispatch: + inputs: + deploy_action: + description: "Action to perform (upgrade, destroy, etc.)" + required: false + default: upgrade + deploy_dry_run: + description: "Run Ansible in check mode" + required: false + default: 'true' + push: + branches: + - main + paths: + - '.github/workflows/iac-pipeline-infrastructure-monitor-server.yml' + +env: + DEPLOY_ACTION: ${{ github.event.inputs.deploy_action || '' }} + DEPLOY_DRY_RUN: ${{ github.event.inputs.deploy_dry_run || '' }} + ANSIBLE_USER: ${{ secrets.VPS_USER }} + ANSIBLE_STDOUT_CALLBACK: yaml + ANSIBLE_LOAD_CALLBACK_PLUGINS: 'true' + +jobs: + pre-setup: + runs-on: ubuntu-latest + steps: + - name: Pre-setup confirmation + run: echo "Pre-setup stage completed" + + deploy: + needs: pre-setup + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + strategy: + matrix: + site: [otel.svc.plus] + steps: + - uses: actions/checkout@v4 + + - name: Determine deployment context + run: | + set -euo pipefail + dry_run="${DEPLOY_DRY_RUN}" + if [[ "${GITHUB_EVENT_NAME}" != "workflow_dispatch" ]]; then + dry_run="true" + fi + echo "EFFECTIVE_DRY_RUN=${dry_run}" >> "$GITHUB_ENV" + action="${DEPLOY_ACTION:-upgrade}" + if [[ -z "${action}" ]]; then + action="upgrade" + fi + echo "EFFECTIVE_DEPLOY_ACTION=${action}" >> "$GITHUB_ENV" + + - name: Checkout infrastructure playbooks + uses: actions/checkout@v4 + with: + repository: svc-design/gitops + path: gitops + + - name: Install Ansible + run: | + set -euo pipefail + python3 -m pip install --upgrade pip + python3 -m pip install ansible + cat <<'CFG' > ~/.ansible.cfg + [defaults] + stdout_callback = yaml + callbacks_enabled = profile_tasks,timer + bin_ansible_callbacks = True + CFG + + - name: Configure Ansible Vault password + env: + ANSIBLE_VAULT_PASSWORD: ${{ secrets.ANSIBLE_VAULT_PASSWORD }} + run: | + set -euo pipefail + if [[ -z "${ANSIBLE_VAULT_PASSWORD:-}" ]]; then + echo "ANSIBLE_VAULT_PASSWORD secret is not configured" >&2 + exit 1 + fi + printf '%s' "${ANSIBLE_VAULT_PASSWORD}" > ~/.vault_password + chmod 600 ~/.vault_password + + - name: Configure SSH access + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + run: | + set -euo pipefail + install -m 700 -d ~/.ssh + echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -H "${{ matrix.site }}" >> ~/.ssh/known_hosts + + - name: Prepare provisioning inputs + id: prepare_provisioning + working-directory: gitops + run: | + set -euo pipefail + + echo "inventory=playbooks/inventory.ini" >> "$GITHUB_OUTPUT" + echo "skip=false" >> "$GITHUB_OUTPUT" + + extra_flags=() + if [[ "${EFFECTIVE_DRY_RUN}" == "true" ]]; then + extra_flags+=("--check") + fi + printf 'extra_flags=%s\n' "${extra_flags[*]}" >> "$GITHUB_OUTPUT" + + monitor_playbook="playbooks/deploy_monitor_server.yml" + if [[ ! -f "$monitor_playbook" ]]; then + echo "Required playbook ${monitor_playbook} was not found" >&2 + exit 1 + fi + echo "monitor_playbook=${monitor_playbook}" >> "$GITHUB_OUTPUT" + + case "${EFFECTIVE_DEPLOY_ACTION}" in + destroy|backup|backup-rollout|restore) + echo "skip=true" >> "$GITHUB_OUTPUT" + echo "Action ${EFFECTIVE_DEPLOY_ACTION} is not supported for monitor server provisioning" >&2 + exit 0 + ;; + esac + + - name: Provision Monitor Server + if: steps.prepare_provisioning.outputs.skip != 'true' + working-directory: gitops + env: + INVENTORY: ${{ steps.prepare_provisioning.outputs.inventory }} + EXTRA_FLAGS: ${{ steps.prepare_provisioning.outputs.extra_flags }} + MONITOR_PLAYBOOK: ${{ steps.prepare_provisioning.outputs.monitor_playbook }} + run: | + set -euo pipefail + flags=() + if [[ -n "${EXTRA_FLAGS}" ]]; then + flags+=(${EXTRA_FLAGS}) + fi + ansible-playbook -i "${INVENTORY}" "${MONITOR_PLAYBOOK}" "${flags[@]}" --limit "${{ matrix.site }}"