152 lines
7.2 KiB
YAML
152 lines
7.2 KiB
YAML
---
|
|
# ==============================================================================
|
|
# ЭТАП 1: Сбор сертификатов с хоста storm.bit-it.ru на ваш ПК
|
|
# ==============================================================================
|
|
- name: Безопасный сбор всех SSL-сертификатов с эталонного хоста
|
|
hosts: storm.bit-it.ru
|
|
become: true
|
|
vars:
|
|
local_tmp_dir: "/tmp/ansible_certs"
|
|
target_certs: []
|
|
ansible_python_interpreter: /usr/bin/python3
|
|
tasks:
|
|
- name: Динамический поиск папок доменов
|
|
ansible.builtin.find:
|
|
paths: "/etc/letsencrypt/live"
|
|
file_type: directory
|
|
recurse: false
|
|
excludes: "all,README"
|
|
register: found_live_dirs
|
|
|
|
- name: Формирование списка доменов с учетом фильтрации
|
|
ansible.builtin.set_fact:
|
|
dynamic_domains: "{{ (found_live_dirs.files | map(attribute='path') | map('basename') | list) if target_certs | length == 0 else (found_live_dirs.files | map(attribute='path') | map('basename') | intersect(target_certs) | list) }}"
|
|
cacheable: true
|
|
|
|
- name: Проверка, что список доменов для переноса не пуст
|
|
ansible.builtin.meta: end_play
|
|
when: dynamic_domains | length == 0
|
|
|
|
- name: Вывод списка доменов, выбранных для синхронизации
|
|
ansible.builtin.debug:
|
|
msg: "Будут синхронизированы следующие сертификаты: {{ dynamic_domains }}"
|
|
|
|
- name: МАКСИМАЛЬНАЯ БЕЗОПАСНОСТЬ - Создание изолированной папок на вашем ПК
|
|
ansible.builtin.file:
|
|
path: "{{ local_tmp_dir }}/{{ item }}"
|
|
state: directory
|
|
mode: '0700'
|
|
delegate_to: localhost
|
|
become: false
|
|
loop: [ 'archive', 'live', 'renewal' ]
|
|
|
|
# --- РЕШЕНИЕ ПРОБЛЕМЫ С ПАПКАМИ ---
|
|
- name: Поиск всех файлов внутри папок archive для выбранных доменов
|
|
ansible.builtin.find:
|
|
paths: "/etc/letsencrypt/archive/{{ item }}"
|
|
file_type: file
|
|
recurse: true
|
|
loop: "{{ dynamic_domains | list }}"
|
|
register: found_archive_files
|
|
|
|
- name: Скачивание файлов archive на ваш ПК
|
|
ansible.builtin.fetch:
|
|
src: "{{ item.1.path }}"
|
|
dest: "{{ local_tmp_dir }}/archive/{{ inventory_hostname }}/{{ item.1.path | relpath('/') }}"
|
|
flat: true
|
|
loop: "{{ found_archive_files.results | subelements('files') }}"
|
|
|
|
- name: Скачивание конфигураций обновления renewal на ваш ПК
|
|
ansible.builtin.fetch:
|
|
src: "/etc/letsencrypt/renewal/{{ item }}.conf"
|
|
dest: "{{ local_tmp_dir }}/renewal/{{ item }}.conf"
|
|
flat: true
|
|
loop: "{{ dynamic_domains | list }}"
|
|
|
|
- name: Скачивание файлов из папок live на ваш ПК
|
|
ansible.builtin.fetch:
|
|
src: "/etc/letsencrypt/live/{{ item.0 }}/{{ item.1 }}.pem"
|
|
dest: "{{ local_tmp_dir }}/live/{{ item.0 }}/{{ item.1 }}.pem"
|
|
flat: true
|
|
loop: "{{ dynamic_domains | product(['cert', 'chain', 'fullchain', 'privkey']) | list }}"
|
|
|
|
# ==============================================================================
|
|
# ЭТАП 2: Раскатка сертификатов СТРОГО на выбранные хосты
|
|
# ==============================================================================
|
|
- name: Раскатка SSL-сертификатов с ПК на целевые хосты и зачистка
|
|
hosts: "{{ target_certs if (target_certs | length > 0) else 'all:!storm.bit-it.ru' }}"
|
|
become: true
|
|
vars:
|
|
local_tmp_dir: "/tmp/ansible_certs"
|
|
source_host_inventory_name: "storm.bit-it.ru"
|
|
ansible_python_interpreter: /usr/bin/python3
|
|
tasks:
|
|
- name: Основной block раскатки
|
|
block:
|
|
- name: Сбор информации о запущенных сервисах на целевом хосте
|
|
ansible.builtin.service_facts:
|
|
|
|
- name: Автоматическое создание всей иерархии папок Let's Encrypt на целевом хосте
|
|
ansible.builtin.file:
|
|
path: "/etc/letsencrypt/{{ item }}"
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: '0755'
|
|
loop: [ 'archive', 'live', 'renewal' ]
|
|
|
|
- name: Копирование содержимого папки archive на целевой сервер
|
|
ansible.builtin.copy:
|
|
src: "{{ local_tmp_dir }}/archive/{{ source_host_inventory_name }}/etc/letsencrypt/archive/{{ inventory_hostname }}/"
|
|
dest: "/etc/letsencrypt/archive/{{ inventory_hostname }}/"
|
|
owner: root
|
|
group: root
|
|
mode: '0600'
|
|
when: inventory_hostname in hostvars[source_host_inventory_name]['dynamic_domains']
|
|
|
|
- name: Копирование конфигураций renewal на целевой сервер
|
|
ansible.builtin.copy:
|
|
src: "{{ local_tmp_dir }}/renewal/{{ inventory_hostname }}.conf"
|
|
dest: "/etc/letsencrypt/renewal/{{ inventory_hostname }}.conf"
|
|
owner: root
|
|
group: root
|
|
mode: '0644'
|
|
when: inventory_hostname in hostvars[source_host_inventory_name]['dynamic_domains']
|
|
|
|
- name: Создание папок доменов внутри директории live
|
|
ansible.builtin.file:
|
|
path: "/etc/letsencrypt/live/{{ inventory_hostname }}"
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: '0700'
|
|
when: inventory_hostname in hostvars[source_host_inventory_name]['dynamic_domains']
|
|
|
|
- name: Нативная сборка относительных символических ссылок в папке live
|
|
ansible.builtin.file:
|
|
src: "../../archive/{{ inventory_hostname }}/{{ item }}1.pem"
|
|
dest: "/etc/letsencrypt/live/{{ inventory_hostname }}/{{ item }}.pem"
|
|
state: link
|
|
force: true
|
|
loop: [ 'cert', 'chain', 'fullchain', 'privkey' ]
|
|
when: inventory_hostname in hostvars[source_host_inventory_name]['dynamic_domains']
|
|
|
|
- name: Автоматический перезапуск активных веб- и почтовых служб
|
|
ansible.builtin.systemd:
|
|
name: "{{ item }}"
|
|
state: restarted
|
|
loop: [ 'dovecot', 'nginx', 'apache2', 'httpd' ]
|
|
when:
|
|
- ansible_facts.services[item + '.service'] is defined
|
|
- ansible_facts.services[item + '.service'].state == 'running'
|
|
- inventory_hostname in hostvars[source_host_inventory_name]['dynamic_domains']
|
|
|
|
always:
|
|
- name: МАКСИМАЛЬНАЯ БЕЗОПАСНОСТЬ - Полное удаление секретных ключей с ПК администратора
|
|
ansible.builtin.file:
|
|
path: "{{ local_tmp_dir }}"
|
|
state: absent
|
|
delegate_to: localhost
|
|
become: false
|
|
run_once: true
|