84 lines
4.3 KiB
YAML
84 lines
4.3 KiB
YAML
---
|
||
# Подъём GitOps-подложки контура: k3s + gitea + vault + bootstrap FluxCD.
|
||
# Отделено от прикладного стека (sarex_services) намеренно: здесь только
|
||
# публичные образы, docker login в приватный реестр не требуется.
|
||
#
|
||
# Порядок важен и поэтому разбит на две волны: flux-bootstrap монтирует
|
||
# ./k3s/kubeconfig.yaml, который k3s-server создаёт только при первом старте.
|
||
# Если поднять всё одной командой, docker может создать на месте отсутствующего
|
||
# файла директорию, и bootstrap упадёт с невнятной ошибкой.
|
||
|
||
- name: Волна 1 — поднять k3s-server и gitea
|
||
ansible.builtin.command:
|
||
cmd: "{{ compose_cmd }} up -d {{ aero_platform_services_wave1 | join(' ') }}"
|
||
chdir: "{{ deploy_dir }}"
|
||
changed_when: true
|
||
|
||
- name: Дождаться kubeconfig от k3s-server
|
||
ansible.builtin.wait_for:
|
||
path: "{{ deploy_dir }}/k3s/kubeconfig.yaml"
|
||
state: present
|
||
timeout: "{{ aero_kubeconfig_timeout }}"
|
||
|
||
# Пустой файл означает, что k3s-server ещё дописывает kubeconfig. Без этой
|
||
# проверки flux-bootstrap может стартовать с нулевым конфигом.
|
||
- name: Убедиться, что kubeconfig не пустой
|
||
ansible.builtin.wait_for:
|
||
path: "{{ deploy_dir }}/k3s/kubeconfig.yaml"
|
||
search_regex: "clusters:"
|
||
timeout: 60
|
||
|
||
- name: Волна 2 — gitea-init, vault(+init) и bootstrap Flux
|
||
ansible.builtin.command:
|
||
cmd: "{{ compose_cmd }} up -d {{ aero_platform_services_wave2 | join(' ') }}"
|
||
chdir: "{{ deploy_dir }}"
|
||
changed_when: true
|
||
|
||
# flux-bootstrap одноразовый: успех = код 0. Забираем его явно, иначе ошибка
|
||
# bootstrap'а останется незамеченной — `compose up -d` о ней не сообщает.
|
||
#
|
||
# `docker compose wait` здесь не годится: для уже завершившегося контейнера он
|
||
# возвращает rc=1 и "no containers for project". Так как `up -d` не дожидается
|
||
# одноразового сервиса, состояние гоночное — поэтому опрашиваем `ps -a`,
|
||
# который корректно отвечает и для running, и для exited.
|
||
#
|
||
# Формат обёрнут в {% raw %}: это Go-шаблон docker'а, и без raw Jinja попыталась
|
||
# бы раскрыть {{.State.Status}} как свою переменную. Аргументы передаём списком —
|
||
# у `command` нет шелла, и строка со скобками разбилась бы по пробелу.
|
||
- name: Дождаться завершения flux-bootstrap
|
||
ansible.builtin.command:
|
||
argv:
|
||
- "{{ compose_cmd.split()[0] }}"
|
||
- inspect
|
||
- "-f"
|
||
- "{% raw %}{{.State.Status}} {{.State.ExitCode}}{% endraw %}"
|
||
- flux-bootstrap
|
||
register: aero_flux_bootstrap
|
||
changed_when: false
|
||
retries: 30
|
||
delay: 10
|
||
until: aero_flux_bootstrap.stdout | trim is not match('^running')
|
||
|
||
- name: Показать логи flux-bootstrap при ошибке
|
||
ansible.builtin.command:
|
||
cmd: "{{ compose_cmd }} logs --no-color --tail 50 flux-bootstrap"
|
||
chdir: "{{ deploy_dir }}"
|
||
register: aero_flux_logs
|
||
changed_when: false
|
||
when: aero_flux_bootstrap.stdout.split() | last != "0"
|
||
|
||
- name: Прервать деплой, если bootstrap не удался
|
||
ansible.builtin.fail:
|
||
msg: |
|
||
flux bootstrap завершился с кодом {{ aero_flux_bootstrap.stdout.split() | last }}.
|
||
Логи контейнера:
|
||
{{ aero_flux_logs.stdout | default('(недоступны)') }}
|
||
when: aero_flux_bootstrap.stdout.split() | last != "0"
|
||
|
||
- name: Итог
|
||
ansible.builtin.debug:
|
||
msg:
|
||
- "gitea: http://{{ ansible_host }}:3000 (пользователь {{ gitea_admin_user }}, пароль в aero/.secrets/{{ inventory_hostname }}/GITEA_ADMIN_PASSWORD)"
|
||
- "Flux реконсилирует {{ gitea_org }}/{{ gitea_repo }} → {{ aero_flux_path }}"
|
||
- "Проверка: docker compose exec k3s-server kubectl -n flux-system get kustomizations"
|