ansible-taler-exchange

Ansible playbook to deploy a production Taler Exchange
Log | Files | Refs | README | LICENSE

commit b762722b614360d61a964bf6020d0feb51ef9628
parent 6c0f65e7e2cd57c810fee186c002bdcdf285ebb9
Author: Florian Dold <dold@taler.net>
Date:   Mon, 10 Aug 2026 12:05:18 +0200

Add post-deployment sanity checks

Diffstat:
Mplaybooks/setup.yml | 5+++++
Aroles/post_deployment_checks/defaults/main.yml | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aroles/post_deployment_checks/tasks/main.yml | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 150 insertions(+), 0 deletions(-)

diff --git a/playbooks/setup.yml b/playbooks/setup.yml @@ -87,3 +87,8 @@ when: deploy_monitoring | bool - role: devtesting when: dangerously_enable_devtesting | bool + + post_tasks: + - name: Run post-deployment sanity checks + ansible.builtin.include_role: + name: post_deployment_checks diff --git a/roles/post_deployment_checks/defaults/main.yml b/roles/post_deployment_checks/defaults/main.yml @@ -0,0 +1,76 @@ +--- +post_deployment_check_retries: 10 +post_deployment_check_delay: 1 +post_deployment_http_timeout: 5 + +post_deployment_systemd_checks: + # Exchange + - unit: taler-exchange.target + enabled: true + - unit: taler-exchange-httpd.service + enabled: true + - unit: taler-exchange-wirewatch.service + enabled: true + - unit: taler-exchange-aggregator.service + enabled: true + - unit: taler-exchange-closer.service + enabled: true + - unit: taler-exchange-expire.service + enabled: true + - unit: taler-exchange-transfer.service + enabled: true + - unit: taler-exchange-secmod-cs.service + enabled: true + - unit: taler-exchange-secmod-eddsa.service + enabled: true + - unit: taler-exchange-secmod-rsa.service + enabled: true + - unit: taler-exchange-sanctionscheck.service + enabled: >- + {{ + sanction_list is defined + and 'taler-exchange-sanctionscheck.service' in ansible_facts.services + }} + + # LibEuFin Nexus + - unit: libeufin-nexus-httpd.service + enabled: true + - unit: libeufin-nexus.target + enabled: "{{ use_ebics | bool }}" + - unit: libeufin-nexus-ebics-fetch.service + enabled: "{{ use_ebics | bool }}" + - unit: libeufin-nexus-ebics-submit.service + enabled: "{{ use_ebics | bool }}" + + # Challengers + - unit: sms-challenger-httpd.service + enabled: "{{ deploy_challenger | bool }}" + - unit: email-challenger-httpd.service + enabled: "{{ deploy_challenger | bool }}" + - unit: postal-challenger-httpd.service + enabled: "{{ deploy_challenger | bool }}" + +post_deployment_http_checks: + - name: Taler exchange /config + url: http://localhost/config + unix_socket: /var/run/taler-exchange/httpd/exchange-http.sock + enabled: true + + - name: LibEuFin Nexus /taler-prepared-transfer/config + url: "http://127.0.0.1:{{ libeufin_port }}/taler-prepared-transfer/config" + enabled: true + + - name: SMS Challenger /config + url: http://localhost/config + unix_socket: /run/challenger-sms/challenger-http.sock + enabled: "{{ deploy_challenger | bool }}" + + - name: email Challenger /config + url: http://localhost/config + unix_socket: /run/challenger-email/challenger-http.sock + enabled: "{{ deploy_challenger | bool }}" + + - name: postal Challenger /config + url: http://localhost/config + unix_socket: /run/challenger-postal/challenger-http.sock + enabled: "{{ deploy_challenger | bool }}" diff --git a/roles/post_deployment_checks/tasks/main.yml b/roles/post_deployment_checks/tasks/main.yml @@ -0,0 +1,69 @@ +--- +- name: Gather service facts for optional post-deployment checks + ansible.builtin.service_facts: + +- name: Check that required systemd units are active + ansible.builtin.command: + argv: + - systemctl + - is-active + - --quiet + - "{{ item.unit }}" + loop: "{{ post_deployment_systemd_checks }}" + loop_control: + label: "{{ item.unit }}" + register: post_deployment_systemd_check + changed_when: false + failed_when: false + retries: "{{ post_deployment_check_retries }}" + delay: "{{ post_deployment_check_delay }}" + until: post_deployment_systemd_check.rc == 0 + when: item.enabled | bool + +- name: Check that required HTTP endpoints respond + ansible.builtin.uri: + url: "{{ item.url }}" + unix_socket: "{{ item.unix_socket | default(omit) }}" + status_code: 200 + timeout: "{{ post_deployment_http_timeout }}" + use_proxy: false + loop: "{{ post_deployment_http_checks }}" + loop_control: + label: "{{ item.name }}" + register: post_deployment_http_check + changed_when: false + failed_when: false + retries: "{{ post_deployment_check_retries }}" + delay: "{{ post_deployment_check_delay }}" + until: post_deployment_http_check.status | default(-1) == 200 + when: item.enabled | bool + +- name: Collect failed post-deployment checks + ansible.builtin.set_fact: + post_deployment_failed_systemd_units: >- + {{ + post_deployment_systemd_check.results + | rejectattr('skipped', 'defined') + | rejectattr('rc', 'equalto', 0) + | map(attribute='item.unit') + | list + }} + post_deployment_failed_http_endpoints: >- + {{ + post_deployment_http_check.results + | rejectattr('skipped', 'defined') + | rejectattr('status', 'equalto', 200) + | map(attribute='item.name') + | list + }} + +- name: Report post-deployment sanity check failures + ansible.builtin.assert: + that: + - post_deployment_failed_systemd_units | length == 0 + - post_deployment_failed_http_endpoints | length == 0 + fail_msg: |- + Post-deployment sanity checks failed. + Inactive systemd units: {{ post_deployment_failed_systemd_units | join(', ') or 'none' }} + Unavailable HTTP endpoints: {{ post_deployment_failed_http_endpoints | join(', ') or 'none' }} + success_msg: All post-deployment sanity checks passed.