--- - name: Деплой LXC с контролем уникальности MAC hosts: localhost become: yes gather_facts: no vars: target_name: "default-container" template_snap: "pool/lxc/template-debian12@snap0" target_ds: "pool/lxc/{{ target_name }}" base_lxc_path: "/var/lib/lxc/{{ target_name }}" vlan_id: 30 tasks: - name: 1. Валидация входных данных fail: msg: "Укажите имя: -e 'target_name=имя'" when: target_name == "default-container" - name: 2. Генерация детерминированного MAC-адреса # Берем первые 6 символов sha256 от имени и разбиваем по 2 символа set_fact: generated_mac: "00:16:3e:{{ (target_name | checksum) | truncate(6, False, '') | batch(2) | map('join') | join(':') }}" - name: 3. Сбор существующих MAC-адресов в системе # Ищем строки lxc.net.0.hwaddr во всех конфигах /var/lib/lxc/*/config shell: "grep -h 'lxc.net.0.hwaddr' /var/lib/lxc/*/config | awk '{print $3}' || true" register: existing_macs changed_when: false - name: 4. Проверка на дубликат (если это новый контейнер) fail: msg: "Конфликт! MAC {{ generated_mac }} уже занят другим контейнером." # Проверяем, есть ли сгенерированный мак в списке, # НО игнорируем проверку, если мы просто пересобираем текущий контейнер when: - generated_mac in existing_macs.stdout_lines - not (ansible_check_mode or (base_lxc_path + '/config') is file) - name: 5. Создание ZFS клона community.general.zfs: name: "{{ target_ds }}" origin: "{{ template_snap }}" state: present extra_zfs_properties: mountpoint: legacy - name: 6. Подготовка директории file: path: "{{ base_lxc_path }}" state: directory - name: 7. Запись конфига с фиксированным MAC copy: dest: "{{ base_lxc_path }}/config" content: | lxc.include = /usr/share/lxc/config/common.conf lxc.arch = x86_64 lxc.idmap = u 0 1000000 65536 lxc.idmap = g 0 1000000 65536 lxc.net.0.type = veth lxc.net.0.link = br0 lxc.net.0.flags = up lxc.net.0.name = eth0 lxc.net.0.veth.vlan.id = {{ vlan_id }} lxc.net.0.hwaddr = {{ generated_mac }} lxc.uts.name = {{ target_name }} lxc.rootfs.path = zfs:{{ target_ds }} - name: 8. Запуск контейнера community.general.lxc_container: name: "{{ target_name }}" state: started - name: Итог debug: msg: "Контейнер {{ target_name }} запущен с MAC: {{ generated_mac }} в VLAN {{ vlan_id }}"