02_bench_bootstrap.ymlΒΆ

---
- name: "πŸ” probe site_config.json for '{{ ERPNEXT_SITE_NAME }}'"
  ansible.builtin.shell: |
    set -eo pipefail
    # nocheck: container-exec-resolver  runtime-resolved CID, delegated to the hosting node
    container exec {{ ERPNEXT_BACKEND_LOCAL_CID | quote }} \
      test -f /home/frappe/frappe-bench/sites/{{ ERPNEXT_SITE_NAME }}/site_config.json
  delegate_to: "{{ ERPNEXT_BACKEND_HOST_NODE }}"
  register: erpnext_site_probe
  changed_when: false
  failed_when: false

- name: "πŸ₯Ύ Bootstrap ERPNext site when missing (create + restart + wait for backend)"
  ansible.builtin.include_tasks: 02_bench_bootstrap/create_site.yml
  when: erpnext_site_probe.rc != 0

- name: "πŸ”‘ Realign the Administrator password with the declared one"
  ansible.builtin.shell: |
    set -euo pipefail
    # nocheck: container-exec-resolver  runtime-resolved CID, delegated to the hosting node
    container exec -i -e ADMIN_PASSWORD {{ ERPNEXT_BACKEND_LOCAL_CID | quote }} bash -c '
      bench --site {{ ERPNEXT_SITE_NAME }} set-admin-password "$ADMIN_PASSWORD"
    '
  environment:
    ADMIN_PASSWORD: "{{ ERPNEXT_INITIAL_ADMIN_PASSWORD }}"
  delegate_to: "{{ ERPNEXT_BACKEND_HOST_NODE }}"
  changed_when: true
  no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"

- name: "βœ… ensure encryption_key on site '{{ ERPNEXT_SITE_NAME }}'"
  ansible.builtin.shell: |
    set -euo pipefail
    # nocheck: container-exec-resolver  runtime-resolved CID, delegated to the hosting node
    container exec {{ ERPNEXT_BACKEND_LOCAL_CID | quote }} bash -c '
      grep -q "encryption_key" /home/frappe/frappe-bench/sites/{{ ERPNEXT_SITE_NAME }}/site_config.json || \
      bench --site {{ ERPNEXT_SITE_NAME }} execute frappe.utils.password.create_auth_table 2>/dev/null || true
    '
  delegate_to: "{{ ERPNEXT_BACKEND_HOST_NODE }}"
  changed_when: false

- name: "🏒 ensure the service provider's Company and its accounting basics"
  ansible.builtin.shell:
    cmd: > # nocheck: container-exec-resolver  runtime-resolved CID, delegated to the hosting node
      container exec -i
      -e SITE_NAME -e COMPANY_NAME -e COMPANY_ABBR -e COMPANY_COUNTRY
      {{ ERPNEXT_BACKEND_LOCAL_CID | quote }}
      {{ ERPNEXT_BENCH_PYTHON }}
    stdin: "{{ lookup('ansible.builtin.file', role_path ~ '/files/python/apply/company.py') }}"
  delegate_to: "{{ ERPNEXT_BACKEND_HOST_NODE }}"
  environment:
    SITE_NAME: "{{ ERPNEXT_SITE_NAME }}"
    COMPANY_NAME: "{{ ERPNEXT_COMPANY_NAME }}"
    COMPANY_ABBR: "{{ ERPNEXT_COMPANY_ABBR }}"
    COMPANY_COUNTRY: "{{ ERPNEXT_COMPANY_COUNTRY }}"
  register: erpnext_company_apply
  changed_when: erpnext_company_apply.rc == 0 and (erpnext_company_apply.stdout_lines | last | from_json).created | length > 0

- name: "πŸ“Œ apply API-bot user + bypass setup wizard"
  no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
  ansible.builtin.shell:
    cmd: > # nocheck: container-exec-resolver  runtime-resolved CID, delegated to the hosting node
      container exec -i
      -e SITE_NAME -e API_BOT_LOGIN -e API_BOT_EMAIL -e API_BOT_FIRSTNAME -e API_BOT_LASTNAME -e API_BOT_PASSWORD -e API_KEY_SECRET
      -e API_BOT_EXTRA_ROLES_JSON -e COUNTRY -e CURRENCY -e SERVER_SCRIPTS_ENABLED
      {{ ERPNEXT_BACKEND_LOCAL_CID | quote }}
      {{ ERPNEXT_BENCH_PYTHON }}
    stdin: "{{ lookup('ansible.builtin.file', role_path ~ '/files/python/apply/api_bot.py') }}"
  delegate_to: "{{ ERPNEXT_BACKEND_HOST_NODE }}"
  environment:
    SITE_NAME: "{{ ERPNEXT_SITE_NAME }}"
    API_BOT_LOGIN: "{{ ERPNEXT_API_BOT_USER.username }}"
    API_BOT_EMAIL: "{{ ERPNEXT_API_BOT_USER.email }}"
    API_BOT_FIRSTNAME: "{{ ERPNEXT_API_BOT_USER.firstname }}"
    API_BOT_LASTNAME: "{{ ERPNEXT_API_BOT_USER.lastname }}"
    API_BOT_PASSWORD: "{{ ERPNEXT_API_BOT_PASSWORD }}"
    API_KEY_SECRET: "{{ ERPNEXT_API_KEY_SECRET }}"
    API_BOT_EXTRA_ROLES_JSON: "{{ ERPNEXT_API_BOT_EXTRA_ROLES | to_json }}"
    COUNTRY: "{{ ERPNEXT_COMPANY_COUNTRY }}"
    CURRENCY: "{{ (erpnext_company_apply.stdout_lines | last | from_json).currency }}"
    SERVER_SCRIPTS_ENABLED: "{{ ERPNEXT_SERVER_SCRIPTS_ENABLED }}"
  register: erpnext_api_bot_apply
  changed_when: false

- name: "πŸ“œ align server_script_enabled with services.erpnext.server_scripts"
  ansible.builtin.shell:
    cmd: > # nocheck: container-exec-resolver  runtime-resolved CID, delegated to the hosting node
      container exec -i
      -e SERVER_SCRIPTS_ENABLED
      {{ ERPNEXT_BACKEND_LOCAL_CID | quote }}
      {{ ERPNEXT_BENCH_PYTHON }}
    stdin: "{{ lookup('ansible.builtin.file', role_path ~ '/files/python/apply/server_scripts.py') }}"
  delegate_to: "{{ ERPNEXT_BACKEND_HOST_NODE }}"
  environment:
    SERVER_SCRIPTS_ENABLED: "{{ ERPNEXT_SERVER_SCRIPTS_ENABLED }}"
  register: erpnext_server_scripts_apply
  changed_when: (erpnext_server_scripts_apply.stdout_lines | last | from_json).changed

- name: "πŸ”„ Restart Frappe so every worker reads the new server_script_enabled"
  ansible.builtin.include_tasks: 02_bench_bootstrap/restart_frappe.yml
  when: erpnext_server_scripts_apply is changed