ansible-taler-exchange

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

commit 8cc87221597904db9aaa7e505e3b61b1ed2c6485
parent 75193aceb38788c8790c93bf74cbfe79f20da483
Author: Florian Dold <florian@dold.me>
Date:   Fri, 28 Feb 2025 10:27:40 +0100

misc refactoring and cleanup

Diffstat:
Mansible.cfg | 4+++-
Minventories/host_vars/fdold-acai/test-public.yml | 2+-
Mplaybooks/setup.yml | 2+-
Mroles/auditor/tasks/main.yml | 16++++++++--------
Mroles/challenger/tasks/post-exchange.yml | 2+-
Mroles/challenger/tasks/pre-exchange.yml | 75++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mroles/challenger/templates/etc/taler-exchange/secrets/challenger-email.secret.conf.j2 | 4++--
Mroles/challenger/templates/etc/taler-exchange/secrets/challenger-postal.secret.conf.j2 | 4++--
Mroles/challenger/templates/etc/taler-exchange/secrets/challenger-sms.secret.conf.j2 | 4++--
Aroles/common_packages/files/setup-challenger-client-id-fact | 22++++++++++++++++++++++
Aroles/common_packages/files/setup-secret-fact | 19+++++++++++++++++++
Mroles/common_packages/tasks/main.yml | 16++++++++++++++++
Droles/database/example.taler_postgres.fact | 4----
Mroles/exchange/tasks/main.yml | 12++++++------
Mroles/exchange/templates/etc/taler-exchange/secrets/exchange-accountcredentials-primary.secret.conf.j2 | 2+-
Mroles/libeufin-nexus/tasks/main.yml | 11++++++-----
Mroles/libeufin-nexus/templates/etc/libeufin/libeufin-nexus.conf.j2 | 2+-
Mroles/monitoring/tasks/main.yml | 27++++++++++++++-------------
18 files changed, 149 insertions(+), 79 deletions(-)

diff --git a/ansible.cfg b/ansible.cfg @@ -6,6 +6,8 @@ remote_user = root # Use the YAML callback plugin. stdout_callback = yaml # Use the stdout_callback when running ad-hoc commands. -bin_ansible_callbacks = True +#bin_ansible_callbacks = True use_persistent_connections = True + +pipelining = True diff --git a/inventories/host_vars/fdold-acai/test-public.yml b/inventories/host_vars/fdold-acai/test-public.yml @@ -4,7 +4,7 @@ USE_PREGENERATED_DHPARAM: true # Public variables for a "test" deployment # Deploy challenger? -DEPLOY_CHALLENGER: false +DEPLOY_CHALLENGER: true # Main domain name. DOMAIN_NAME: "topstest.fdold.eu" # Use nightly Taler distro (true/false). diff --git a/playbooks/setup.yml b/playbooks/setup.yml @@ -8,7 +8,7 @@ when: HAVE_SECRETS is undefined roles: - role: common_packages - - role: ansible_pull + # - role: ansible_pull - role: webserver - role: database - role: libeufin-nexus diff --git a/roles/auditor/tasks/main.yml b/roles/auditor/tasks/main.yml @@ -19,8 +19,8 @@ - name: Ensure Taler auditor config dir exists from installation ansible.builtin.stat: path: "/etc/taler-auditor" - register: st - failed_when: not (st.stat.exists is defined and st.stat.exists) + register: st + failed_when: not (st.stat.exists is defined and st.stat.exists) - name: Ensure Taler letsencrypt auditor dir exists from installation file: @@ -37,7 +37,7 @@ owner: root group: root mode: "0644" - notify: restart nginx + notify: Restart nginx - name: Ensure Taler auditor HTTP virtualhost configuration file exists template: @@ -46,14 +46,14 @@ owner: root group: root mode: "0644" - notify: restart nginx + notify: Restart nginx - name: Enable Taler HTTP auditor reverse proxy configuration file: src: /etc/nginx/sites-available/auditor-http.conf dest: /etc/nginx/sites-enabled/auditor-http.conf state: link - notify: restart nginx + notify: Restart nginx # We need to make sure that our handler notifies nginx to restart NOW - name: Flush handlers @@ -87,13 +87,13 @@ src: /etc/nginx/sites-available/auditor-nginx.conf dest: /etc/nginx/sites-enabled/auditor-nginx.conf state: link - notify: restart nginx + notify: Restart nginx - name: Ensure /etc/taler-auditor/conf.d/ directory exists ansible.builtin.stat: path: "/etc/taler-auditor/conf.d/" - register: st - failed_when: not (st.stat.exists is defined and st.stat.exists) + register: st + failed_when: not (st.stat.exists is defined and st.stat.exists) - name: Place taler-auditor master config template: diff --git a/roles/challenger/tasks/post-exchange.yml b/roles/challenger/tasks/post-exchange.yml @@ -29,7 +29,7 @@ dest: /etc/taler-exchange/conf.d/challenger.conf owner: taler-exchange-httpd group: taler-exchange-kyc - mode: "0740" + mode: "0744" - name: Ensure taler-exchange service is is restarted with new configuration service: diff --git a/roles/challenger/tasks/pre-exchange.yml b/roles/challenger/tasks/pre-exchange.yml @@ -107,27 +107,31 @@ state: directory owner: root group: root - mode: "0750" + mode: "0755" - name: Secret setup for sms-challenger - ansible.builtin.shell: - cmd: | - set -o pipefail - echo "[sms-challenger]\nCLIENT_SECRET=secret-token:$(dd if=/dev/random count=1 bs=32 status=none | gnunet-base32)" > /etc/ansible/facts.d/sms-challenger-client-secret.fact + when: not local_facts['sms-challenger-client-secret'] is defined + ansible.builtin.command: + argv: + - setup-secret-fact + - /etc/ansible/facts.d/sms-challenger-client-secret.fact + - "secret-token:" creates: /etc/ansible/facts.d/sms-challenger-client-secret.fact - name: Secret setup for email-challenger - ansible.builtin.shell: - cmd: | - set -o pipefail - echo "[email-challenger]\nCLIENT_SECRET=secret-token:$(dd if=/dev/random count=1 bs=32 status=none | gnunet-base32)" > /etc/ansible/facts.d/email-challenger-client-secret.fact + ansible.builtin.command: + argv: + - setup-secret-fact + - /etc/ansible/facts.d/email-challenger-client-secret.fact + - "secret-token:" creates: /etc/ansible/facts.d/email-challenger-client-secret.fact - name: Secret setup for postal-challenger - ansible.builtin.shell: - cmd: | - set -o pipefail - echo "[postal-challenger]\nCLIENT_SECRET=secret-token:$(dd if=/dev/random count=1 bs=32 status=none | gnunet-base32)" > /etc/ansible/facts.d/postal-challenger-client-secret.fact + ansible.builtin.command: + argv: + - setup-secret-fact + - /etc/ansible/facts.d/postal-challenger-client-secret.fact + - "secret-token:" creates: /etc/ansible/facts.d/postal-challenger-client-secret.fact - name: Force ansible to regather just created fact(s) about challenger @@ -197,26 +201,35 @@ - name: Setup SMS Challenger exchange account ansible.builtin.command: - cmd: | - set -o pipefail - sudo -u challenger-sms challenger-admin -c /etc/challenger/challenger-sms.conf --quiet --add={{ ansible_facts['ansible_local']['sms-challenger-client-secret']['sms-challenger']['client_secret'] }} {{ EXCHANGE_BASE_URL }}kyc-proof/sms-challenger | awk '{print "[sms-challenger]\nCLIENT_ID="$1"\n\n"}' > /etc/ansible/facts.d/sms-challenger-client-id.fact - chdir: /tmp + argv: + - setup-challenger-client-id-fact + - /etc/ansible/facts.d/sms-challenger-client-id.fact + - challenger-sms + - /etc/challenger/challenger-sms.conf + - "{{ ansible_local['sms-challenger-client-secret'] }}" + - "{{ EXCHANGE_BASE_URL }}sms-proof/email-challenger" creates: /etc/ansible/facts.d/sms-challenger-client-id.fact - name: Setup Email Challenger exchange account ansible.builtin.command: - cmd: | - set -o pipefail - sudo -u challenger-email challenger-admin -c /etc/challenger/challenger-email.conf --quiet --add={{ ansible_facts['ansible_local']['email-challenger-client-secret']['email-challenger']['client_secret'] }} {{ EXCHANGE_BASE_URL }}kyc-proof/email-challenger | awk '{print "[email-challenger]\nCLIENT_ID="$1"\n\n"}' > /etc/ansible/facts.d/email-challenger-client-id.fact - chdir: /tmp + argv: + - setup-challenger-client-id-fact + - /etc/ansible/facts.d/email-challenger-client-id.fact + - challenger-email + - /etc/challenger/challenger-email.conf + - "{{ ansible_local['email-challenger-client-secret'] }}" + - "{{ EXCHANGE_BASE_URL }}kyc-proof/email-challenger" creates: /etc/ansible/facts.d/email-challenger-client-id.fact - name: Setup Postal Challenger exchange account ansible.builtin.command: - cmd: | - set -o pipefail - sudo -u challenger-postal challenger-admin -c /etc/challenger/challenger-postal.conf --quiet --add={{ ansible_facts['ansible_local']['postal-challenger-client-secret']['postal-challenger']['client_secret'] }} {{ EXCHANGE_BASE_URL }}kyc-proof/postal-challenger | awk '{print "[postal-challenger]\nCLIENT_ID="$1"\n\n"}' > /etc/ansible/facts.d/postal-challenger-client-id.fact - chdir: /tmp + argv: + - setup-challenger-client-id-fact + - /etc/ansible/facts.d/postal-challenger-client-id.fact + - challenger-postal + - /etc/challenger/challenger-postal.conf + - "{{ ansible_local['postal-challenger-client-secret'] }}" + - "{{ EXCHANGE_BASE_URL }}kyc-proof/postal-challenger" creates: /etc/ansible/facts.d/postal-challenger-client-id.fact - name: Force ansible to regather fact(s) just created about sms-challenger @@ -284,7 +297,7 @@ src: /etc/nginx/sites-available/sms-challenger-http.conf dest: /etc/nginx/sites-enabled/sms-challenger-http.conf state: link - notify: restart nginx + notify: Restart nginx - name: Place email challenger HTTP Nginx configuration ansible.builtin.template: @@ -307,7 +320,7 @@ src: /etc/nginx/sites-available/email-challenger-http.conf dest: /etc/nginx/sites-enabled/email-challenger-http.conf state: link - notify: restart nginx + notify: Restart nginx - name: Place postal challenger HTTP configuration ansible.builtin.template: @@ -330,7 +343,7 @@ src: /etc/nginx/sites-available/postal-challenger-http.conf dest: /etc/nginx/sites-enabled/postal-challenger-http.conf state: link - notify: restart nginx + notify: Restart nginx # We need to make sure that our handler notifies nginx to restart NOW - name: Flush handlers @@ -411,18 +424,18 @@ src: /etc/nginx/sites-available/sms-challenger-nginx.conf dest: /etc/nginx/sites-enabled/sms-challenger-nginx.conf state: link - notify: restart nginx + notify: Restart nginx - name: Enable email challenger reverse proxy configuration file: src: /etc/nginx/sites-available/email-challenger-nginx.conf dest: /etc/nginx/sites-enabled/email-challenger-nginx.conf state: link - notify: restart nginx + notify: Restart nginx - name: Enable postal challenger reverse proxy configuration file: src: /etc/nginx/sites-available/postal-challenger-nginx.conf dest: /etc/nginx/sites-enabled/postal-challenger-nginx.conf state: link - notify: restart nginx + notify: Restart nginx diff --git a/roles/challenger/templates/etc/taler-exchange/secrets/challenger-email.secret.conf.j2 b/roles/challenger/templates/etc/taler-exchange/secrets/challenger-email.secret.conf.j2 @@ -4,8 +4,8 @@ KYC_OAUTH2_VALIDITY = 2 years KYC_OAUTH2_AUTHORIZE_URL = https://email.challenger.{{ DOMAIN_NAME }}/authorize#setup KYC_OAUTH2_TOKEN_URL = https://email.challenger.{{ DOMAIN_NAME }}/token KYC_OAUTH2_INFO_URL = https://email.challenger.{{ DOMAIN_NAME }}/info -KYC_OAUTH2_CLIENT_ID = {{ ansible_facts['ansible_local']['email-challenger-client-id']['email-challenger']['client_id'] }} -KYC_OAUTH2_CLIENT_SECRET = {{ ansible_facts['ansible_local']['email-challenger-client-secret']['email-challenger']['client_secret'] }} +KYC_OAUTH2_CLIENT_ID = {{ ansible_local['email-challenger-client-id'] }} +KYC_OAUTH2_CLIENT_SECRET = {{ ansible_local['email-challenger-client-secret'] }} KYC_OAUTH2_POST_URL = {{ KYC_THANK_YOU_URL }} # FIXME: check this is OK... KYC_OAUTH2_CONVERTER_HELPER = /usr/bin/cat diff --git a/roles/challenger/templates/etc/taler-exchange/secrets/challenger-postal.secret.conf.j2 b/roles/challenger/templates/etc/taler-exchange/secrets/challenger-postal.secret.conf.j2 @@ -4,8 +4,8 @@ KYC_OAUTH2_VALIDITY = 2 years KYC_OAUTH2_AUTHORIZE_URL = https://postal.challenger.{{ DOMAIN_NAME }}/authorize#setup KYC_OAUTH2_TOKEN_URL = https://postal.challenger.{{ DOMAIN_NAME }}/token KYC_OAUTH2_INFO_URL = https://postal.challenger.{{ DOMAIN_NAME }}/info -KYC_OAUTH2_CLIENT_ID = {{ ansible_facts['ansible_local']['postal-challenger-client-id']['postal-challenger']['client_id'] }} -KYC_OAUTH2_CLIENT_SECRET = {{ ansible_facts['ansible_local']['postal-challenger-client-secret']['postal-challenger']['client_secret'] }} +KYC_OAUTH2_CLIENT_ID = {{ ansible_local['postal-challenger-client-id'] }} +KYC_OAUTH2_CLIENT_SECRET = {{ ansible_local['postal-challenger-client-secret'] }} KYC_OAUTH2_POST_URL = {{ KYC_THANK_YOU_URL }} # FIXME: check this is OK... KYC_OAUTH2_CONVERTER_HELPER = /usr/bin/cat diff --git a/roles/challenger/templates/etc/taler-exchange/secrets/challenger-sms.secret.conf.j2 b/roles/challenger/templates/etc/taler-exchange/secrets/challenger-sms.secret.conf.j2 @@ -4,8 +4,8 @@ KYC_OAUTH2_VALIDITY = 2 years KYC_OAUTH2_AUTHORIZE_URL = https://sms.challenger.{{ DOMAIN_NAME }}/authorize#setup KYC_OAUTH2_TOKEN_URL = https://sms.challenger.{{ DOMAIN_NAME }}/token KYC_OAUTH2_INFO_URL = https://sms.challenger.{{ DOMAIN_NAME }}/info -KYC_OAUTH2_CLIENT_ID = {{ ansible_facts['ansible_local']['sms-challenger-client-id']['sms-challenger']['client_id'] }} -KYC_OAUTH2_CLIENT_SECRET = {{ ansible_facts['ansible_local']['sms-challenger-client-secret']['sms-challenger']['client_secret'] }} +KYC_OAUTH2_CLIENT_ID = {{ ansible_local['sms-challenger-client-id'] }} +KYC_OAUTH2_CLIENT_SECRET = {{ ansible_local['sms-challenger-client-secret'] }} KYC_OAUTH2_POST_URL = {{ KYC_THANK_YOU_URL }} # FIXME: check this is OK... KYC_OAUTH2_CONVERTER_HELPER = /usr/bin/cat diff --git a/roles/common_packages/files/setup-challenger-client-id-fact b/roles/common_packages/files/setup-challenger-client-id-fact @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +# Helper script, intented to be used by ansible +# to generate a fact file. + +if [[ $# < 4 ]]; then + echo "Usage: $0 <fact_file> <user> <conf> <client_secret> <url>" >&2 + exit 1 +fi + +set -eu + +fact_file=$1 +myuser=$2 +conf=$3 +client_secret=$4 +url=$5 + +client_id=$(sudo -u "$myuser" challenger-admin -c "$conf" --quiet --add="$client_secret" "$url") + +# Output as JSON string +echo "\"$client_id\"" > "$fact_file" diff --git a/roles/common_packages/files/setup-secret-fact b/roles/common_packages/files/setup-secret-fact @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +if [[ $# < 1 ]]; then + echo "Usage: $0 <fact_file> [prefix]" + exit 1 +fi + +set -eu +set -o pipefail +set -x + +SECRET=$(dd if=/dev/random count=1 bs=32 status=none | gnunet-base32) + +jq \ + -n \ + --arg s "$SECRET" \ + --arg p "${2:-}" \ + '"\($p)\($s)"' \ + > "$1" diff --git a/roles/common_packages/tasks/main.yml b/roles/common_packages/tasks/main.yml @@ -78,6 +78,22 @@ state: latest when: ansible_os_family == 'Debian' +- name: Install setup-secret-fact helper + ansible.builtin.copy: + src: setup-secret-fact + dest: /bin/setup-secret-fact + owner: root + group: root + mode: "0744" + +- name: Install setup-challenger-client-id-fact helper + ansible.builtin.copy: + src: setup-challenger-client-id-fact + dest: /bin/setup-challenger-client-id-fact + owner: root + group: root + mode: "0744" + - name: Generate dhparam.pem command: openssl dhparam -out dhparam.pem 4096 args: diff --git a/roles/database/example.taler_postgres.fact b/roles/database/example.taler_postgres.fact @@ -1,4 +0,0 @@ -{ - "password": "" - "db_uri": "unix://..." or "tls://" -} diff --git a/roles/exchange/tasks/main.yml b/roles/exchange/tasks/main.yml @@ -38,7 +38,7 @@ src: /etc/nginx/sites-available/exchange-http.conf dest: /etc/nginx/sites-enabled/exchange-http.conf state: link - notify: restart nginx + notify: Restart nginx # We need to make sure that our handler notifies nginx to restart NOW - name: Flush handlers @@ -72,13 +72,13 @@ src: /etc/nginx/sites-available/exchange-nginx.conf dest: /etc/nginx/sites-enabled/exchange-nginx.conf state: link - notify: restart nginx + notify: Restart nginx - name: Ensure /etc/taler-exchange/config.d/ directory exists ansible.builtin.stat: path: "/etc/taler-exchange/conf.d/" - register: st - failed_when: not (st.stat.exists defined and st.stat.exists) + register: st + failed_when: not (st.stat.exists is defined and st.stat.exists) - name: Place taler-exchange business config ansible.builtin.template: @@ -99,8 +99,8 @@ - name: Check that /etc/taler-exchange/secrets/ directory exists ansible.builtin.stat: path: "/etc/taler-exchange/secrets/" - register: st - failed_when: not (st.stat.exists is defined and st.stat.exists) + register: st + failed_when: not (st.stat.exists is defined and st.stat.exists) - name: Place taler-exchange account credentials ansible.builtin.template: diff --git a/roles/exchange/templates/etc/taler-exchange/secrets/exchange-accountcredentials-primary.secret.conf.j2 b/roles/exchange/templates/etc/taler-exchange/secrets/exchange-accountcredentials-primary.secret.conf.j2 @@ -1,4 +1,4 @@ [exchange-accountcredentials-primary] WIRE_GATEWAY_AUTH_METHOD = bearer WIRE_GATEWAY_URL = "http://localhost:{{ LIBEUFIN_PORT }}/taler-wire-gateway/" -TOKEN = {{ ansible_facts['ansible_local']['libeufin-nexus-access-token']['libeufin-nexus']['auth_bearer_token'] }} +TOKEN = {{ ansible_local['libeufin-nexus-access-token'] }} diff --git a/roles/libeufin-nexus/tasks/main.yml b/roles/libeufin-nexus/tasks/main.yml @@ -36,15 +36,16 @@ file: path: "/etc/ansible/facts.d/" state: directory - mode: "0755" + mode: "0700" owner: root group: root - name: Libeufin-nexus access secret setup - ansible.builtin.shell: - cmd: | - set -o pipefail - echo "[libeufin-nexus]\nAUTH_BEARER_TOKEN=secret-token:$(dd if=/dev/random count=1 bs=32 status=none | gnunet-base32)" > /etc/ansible/facts.d/libeufin-nexus-access-token.fact + ansible.builtin.command: + argv: + - setup-secret-fact + - /etc/ansible/facts.d/libeufin-nexus-access-token.fact + - "secret-token:" creates: /etc/ansible/facts.d/libeufin-nexus-access-token.fact - name: Libeufin-nexus force ansible to regather just created fact(s) diff --git a/roles/libeufin-nexus/templates/etc/libeufin/libeufin-nexus.conf.j2 b/roles/libeufin-nexus/templates/etc/libeufin/libeufin-nexus.conf.j2 @@ -42,7 +42,7 @@ CONFIG=postgres:///libeufin [nexus-httpd-wire-gateway-api] ENABLED = YES AUTH_METHOD = bearer -TOKEN = {{ ansible_facts['ansible_local']['libeufin-nexus-access-token']['libeufin-nexus']['auth_bearer_token'] }} +TOKEN = {{ ansible_local['libeufin-nexus-access-token'] }} # FIXME: is this supported by libeufin? @inline-secret@ nexus-ebics libeufin-nexus-ebics.conf diff --git a/roles/monitoring/tasks/main.yml b/roles/monitoring/tasks/main.yml @@ -66,7 +66,7 @@ owner: root group: root mode: "0644" - notify: restart nginx + notify: Restart nginx - name: Ensure Taler monitoring HTTP virtualhost configuration file exists template: @@ -75,14 +75,22 @@ owner: root group: root mode: "0644" - notify: restart nginx + notify: Restart nginx - name: Enable Taler monitoring HTTP reverse proxy configuration file: src: /etc/nginx/sites-available/monitoring-http.conf dest: /etc/nginx/sites-enabled/monitoring-http.conf state: link - notify: restart nginx + notify: Restart nginx + +- name: Enable Taler monitoring reverse proxy configuration + file: + src: /etc/nginx/sites-available/monitoring-nginx.conf + dest: /etc/nginx/sites-enabled/monitoring-nginx.conf + state: link + notify: Restart nginx + # We need to make sure that our handler notifies nginx to restart NOW - name: Flush handlers @@ -111,13 +119,6 @@ domains: - "monitoring.{{ DOMAIN_NAME }}" -- name: Enable Taler monitoring reverse proxy configuration - file: - src: /etc/nginx/sites-available/monitoring-nginx.conf - dest: /etc/nginx/sites-enabled/monitoring-nginx.conf - state: link - notify: restart nginx - - name: Create prometheus database user community.postgresql.postgresql_user: name: prometheus @@ -157,7 +158,7 @@ owner: root group: root mode: "0644" - notify: restart node-exporter + notify: Restart node-exporter - name: Configure postgres-exporter copy: @@ -166,7 +167,7 @@ owner: root group: root mode: "0644" - notify: restart postgres-exporter + notify: Restart postgres-exporter - name: Configure nginx-exporter copy: @@ -175,7 +176,7 @@ owner: root group: root mode: "0644" - notify: restart nginx-exporter + notify: Restart nginx-exporter - name: Configure prometheus master copy: