Files
poc-frr-anycast/ansible/roles/frr_anycast/tasks/main.yml
T
ayurishchevandClaude Sonnet 5 b2b7306a3c Generalize frr_anycast role, add site-cloud environment (4 nodes, prepend, sNAT)
По updated_dia.png: новое окружение "Облачная площадка" (vr01-vr04, AS 65200,
anycast 172.31.255.10/32) с двумя внешними BGP-каналами — основным (ASN 65104,
без as-path prepend) и резервным (ASN 65103, с prepend на всех узлах) — плюс
sNAT (nftables masquerade) на внешнем интерфейсе.

Роль frr_anycast обобщена под это: вместо двух жёстко именованных соседей —
список bgp_neighbors произвольной длины с флагом prepend; sNAT/ip_forward —
опциональный блок (enable_snat). Площадка A мигрирована на новый формат
host_vars/group_vars без изменения site-a.env и без изменения рендера —
render-check.sh (golden-diff) по-прежнему проходит 6/6.

Для site-cloud (окружение новое, ВМ не подняты) добавлен render-check-cloud.sh
с grep-инвариантами: 4 соседа на узел, prepend только на резервном канале,
nftables masquerade на внешнем интерфейсе — 56/56 проверок пройдено.

run.sh обобщён на несколько окружений: инвентарь по имени playbook'а,
env-файл через SITE_ENV_FILE (алиас SITE_A_ENV_FILE сохранён).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bc3HkMiDwooSyLBLoMKNyF
2026-09-09 20:59:40 +03:00

112 lines
3.6 KiB
YAML

---
- name: Pre-flight | приватные интерфейсы должны быть уже сконфигурированы Terraform-слоем
ansible.builtin.assert:
that:
- priv1_iface in ansible_facts.interfaces
- priv2_iface in ansible_facts.interfaces
- ansible_facts[priv1_iface]['active'] | default(false)
- ansible_facts[priv2_iface]['active'] | default(false)
fail_msg: >-
Интерфейсы {{ priv1_iface }}/{{ priv2_iface }} не найдены или не активны.
Ожидается, что Terraform-провижининг уже создал и поднял их до запуска
этого playbook.
success_msg: "Приватные интерфейсы {{ priv1_iface }} и {{ priv2_iface }} на месте."
- name: Pre-flight | внешний интерфейс должен быть на месте (нужен для sNAT egress)
ansible.builtin.assert:
that:
- ext_iface in ansible_facts.interfaces
- ansible_facts[ext_iface]['active'] | default(false)
fail_msg: >-
Внешний интерфейс {{ ext_iface }} не найден или не активен — он нужен
как egress для sNAT (enable_snat: true).
success_msg: "Внешний интерфейс {{ ext_iface }} на месте."
when: enable_snat | bool
- name: FRR APT-репозиторий | добавить GPG-ключ
ansible.builtin.get_url:
url: https://deb.frrouting.org/frr/keys.gpg
dest: /usr/share/keyrings/frrouting.gpg
mode: "0644"
- name: FRR APT-репозиторий | добавить источник пакетов
ansible.builtin.apt_repository:
repo: >-
deb [signed-by=/usr/share/keyrings/frrouting.gpg]
https://deb.frrouting.org/frr {{ ansible_distribution_release }} {{ frr_apt_series }}
filename: frr
state: present
update_cache: true
- name: Установить пакеты FRR
ansible.builtin.apt:
name: "{{ frr_packages }}"
state: present
- name: Конфиг | /etc/frr/daemons
ansible.builtin.template:
src: daemons.j2
dest: "{{ frr_daemons_path }}"
owner: frr
group: frr
mode: "0640"
notify: Restart frr
- name: Конфиг | /etc/frr/frr.conf
ansible.builtin.template:
src: frr.conf.j2
dest: "{{ frr_conf_path }}"
owner: frr
group: frr
mode: "0640"
notify: Restart frr
- name: Сеть | netplan-конфиг для dummy0 (anycast)
ansible.builtin.template:
src: dummy0.netplan.yml.j2
dest: "{{ netplan_dummy_config_path }}"
owner: root
group: root
mode: "0600"
notify:
- Apply netplan
- Restart frr
- name: FRR | сервис включён и запущен
ansible.builtin.systemd:
name: frr
enabled: true
state: started
- name: sNAT | включить net.ipv4.ip_forward персистентно
ansible.builtin.lineinfile:
path: /etc/sysctl.d/99-frr-anycast-forward.conf
line: net.ipv4.ip_forward=1
create: true
mode: "0644"
notify: Reload sysctl
when: enable_snat | bool
- name: sNAT | установить nftables
ansible.builtin.apt:
name: nftables
state: present
when: enable_snat | bool
- name: sNAT | конфиг /etc/nftables.conf (masquerade на внешнем интерфейсе)
ansible.builtin.template:
src: nftables.conf.j2
dest: "{{ nftables_conf_path }}"
owner: root
group: root
mode: "0640"
notify: Reload nftables
when: enable_snat | bool
- name: sNAT | сервис nftables включён и запущен
ansible.builtin.systemd:
name: nftables
enabled: true
state: started
when: enable_snat | bool