--- - hosts: localhost gather_facts: false vars: # Получаем preset из переменной окружения или используем default preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}" preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml" # Fallback значения если preset файл не найден docker_network: labnet generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini" images: alt: "inecs/ansible-lab:alt-linux-latest" astra: "inecs/ansible-lab:astra-linux-latest" rhel: "inecs/ansible-lab:rhel-latest" centos: "inecs/ansible-lab:centos-latest" alma: "inecs/ansible-lab:alma-latest" rocky: "inecs/ansible-lab:rocky-latest" redos: "inecs/ansible-lab:redos-latest" ubuntu: "inecs/ansible-lab:ubuntu-latest" debian: "inecs/ansible-lab:debian-latest" systemd_defaults: privileged: true command: "/sbin/init" volumes: - "/sys/fs/cgroup:/sys/fs/cgroup:ro" tmpfs: ["/run", "/run/lock"] capabilities: ["SYS_ADMIN"] hosts: - name: u1 family: debian groups: [test] tasks: # - name: Install required collections # command: ansible-galaxy collection install -r /workspace/requirements.yml # delegate_to: localhost # ignore_errors: true # register: collections_install # changed_when: false # run_once: true # become: true # vars: # ansible_python_interpreter: /usr/bin/python3 # environment: # ANSIBLE_COLLECTIONS_PATH: /usr/share/ansible/collections - name: Load preset configuration include_vars: "{{ preset_file }}" when: preset_file is file ignore_errors: true - name: Ensure network exists community.docker.docker_network: name: "{{ docker_network }}" state: present # SYSTEMD nodes - name: Pull systemd images community.docker.docker_image: name: "{{ images[item.family] }}" source: pull loop: "{{ hosts | selectattr('type','undefined') | list }}" loop_control: { label: "{{ item.name }}" } when: item.family is defined and images[item.family] is defined - name: Start systemd nodes community.docker.docker_container: name: "{{ item.name }}" image: "{{ images[item.family] }}" networks: - name: "{{ docker_network }}" privileged: "{{ systemd_defaults.privileged }}" command: "{{ systemd_defaults.command }}" volumes: "{{ systemd_defaults.volumes | default([]) + (item.volumes | default([])) }}" tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}" capabilities: "{{ systemd_defaults.capabilities | default([]) }}" published_ports: "{{ item.publish | default([]) }}" env: "{{ item.env | default({}) }}" # Специальные настройки для Astra Linux security_opts: "{{ ['seccomp=unconfined', 'apparmor=unconfined'] if item.family == 'astra' else [] }}" state: started restart_policy: unless-stopped loop: "{{ hosts | selectattr('type','undefined') | list }}" loop_control: { label: "{{ item.name }}" } when: item.family is defined and images[item.family] is defined # DinD nodes - name: Start DinD nodes (docker:27-dind) community.docker.docker_container: name: "{{ item.name }}" image: "docker:27-dind" networks: - name: "{{ docker_network }}" privileged: true env: DOCKER_TLS_CERTDIR: "" published_ports: "{{ item.publish | default([]) }}" volumes: "{{ (item.volumes | default([])) + [item.name + '-docker:/var/lib/docker'] }}" state: started restart_policy: unless-stopped loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}" loop_control: { label: "{{ item.name }}" } # DOoD nodes (mount docker.sock) - name: Start DOoD nodes (systemd + docker.sock mount) community.docker.docker_container: name: "{{ item.name }}" image: "{{ images[item.family] }}" networks: - name: "{{ docker_network }}" privileged: "{{ systemd_defaults.privileged }}" command: "{{ systemd_defaults.command }}" volumes: "{{ (systemd_defaults.volumes | default([])) + ['/var/run/docker.sock:/var/run/docker.sock'] + (item.volumes | default([])) }}" tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}" capabilities: "{{ systemd_defaults.capabilities | default([]) }}" published_ports: "{{ item.publish | default([]) }}" env: "{{ item.env | default({}) }}" state: started restart_policy: unless-stopped loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}" loop_control: { label: "{{ item.name }}" } when: item.family is defined and images[item.family] is defined # Build groups map - name: Initialize groups map set_fact: groups_map: {} - name: Append hosts to groups set_fact: groups_map: "{{ groups_map | combine({ item_group: (groups_map[item_group] | default([])) + [item_name] }) }}" loop: "{{ hosts | subelements('groups', skip_missing=True) }}" loop_control: label: "{{ item.0.name }}" vars: item_name: "{{ item.0.name }}" item_group: "{{ item.1 }}" # Render inventory - name: Render inventory ini set_fact: inv_content: | [all:vars] ansible_connection=community.docker.docker ansible_python_interpreter=/usr/bin/python3 {% for group, members in (groups_map | dictsort) %} [{{ group }}] {% for h in members %}{{ h }} {% endfor %} {% endfor %} [all] {% for h in hosts %}{{ h.name }} {% endfor %} - name: Write inventory file copy: dest: "{{ generated_inventory }}" content: "{{ inv_content }}" mode: "0644" - name: Display inventory summary debug: msg: | 📋 Inventory Summary: - Total hosts: {{ hosts | length }} - Groups: {{ groups_map.keys() | list | join(', ') }} - Systemd nodes: {{ hosts | selectattr('type','undefined') | list | length }} - DinD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }} - DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}