Ansible #12: Массовая настройка Linux-серверов
| Подробности урока | |
|---|---|
| Уровень сложности | Лёгкий |
| Права root | Требуются |
| Требования | Терминал Linux |
| Категория | Установка ПО |
| Совместимость с ОС | Debian, Ubuntu |
| Примерное время чтения | 20 мин |
Введение
В предыдущей статье мы настроили отдельного пользователя, SSH-ключ и безопасный доступ к серверу. Теперь соберем все эти действия в единый сценарий.
Представим, что необходимо подготовить сразу несколько новых Linux-серверов. На каждом из них нужно выполнить примерно один и тот же набор операций:
-
обновить список пакетов;
-
установить базовые утилиты;
-
настроить часовой пояс;
-
установить и запустить необходимые системные службы;
-
создать пользователя для администрирования;
-
добавить SSH-ключ;
-
настроить
sudo; -
привести SSH к единому состоянию;
-
задать hostname.
Вручную это означает подключаться к каждому серверу и повторять одни и те же команды. С Ansible достаточно описать необходимое состояние один раз и запустить один Playbook.
Подготовка Inventory
Для примера возьмем три сервера:
[web]
web1 ansible_host=192.168.88.40
web2 ansible_host=192.168.88.41
На новых серверах Ansible пока подключается под root.
Проверяем доступ:
ansible -i inventory web -m ping -u root
Если все серверы доступны:
можно переходить к подготовке.
Обновление списка пакетов
Начнем с обновления информации о пакетах:
- name: Обновление списка пакетов
ansible.builtin.apt:
update_cache: true
Для Debian и Ubuntu этого достаточно, чтобы обновить локальный индекс APT.
Саму полную систему на этом этапе обновлять необязательно. В инфраструктуре обновление пакетов и первоначальная настройка сервера часто являются отдельными процессами.
Установка базовых пакетов
На новом сервере обычно нужны хотя бы базовые инструменты:
- name: Установка базовых пакетов
ansible.builtin.apt:
name:
- curl
- wget
- vim
- htop
- unzip
- ca-certificates
state: present
Здесь используется список пакетов.
Ansible самостоятельно проверит, установлены ли они уже. Поэтому повторный запуск Playbook не будет каждый раз устанавливать пакеты заново.
Настройка часового пояса
Для серверов важно использовать одинаковый часовой пояс.
Например, установим:
Europe/Moscow
Для этого можно использовать модуль community.general.timezone.
Если коллекция еще не установлена:
ansible-galaxy collection install community.general
После этого добавляем:
- name: Настройка часового пояса
community.general.timezone:
name: Europe/Moscow
Проверить результат на сервере можно:
timedatectl
Настройка времени
Для корректной работы журналов, сертификатов, баз данных и систем мониторинга серверы должны иметь правильное время. На Debian и Ubuntu можно использовать systemd-timesyncd.
Установим и запустим его:
- name: Установка systemd-timesyncd
ansible.builtin.apt:
name: systemd-timesyncd
state: present
- name: Запуск синхронизации времени
ansible.builtin.service:
name: systemd-timesyncd
state: started
enabled: true
После этого проверить состояние можно:
timedatectl status
Создание административного пользователя
Теперь создадим пользователя deploy.
- name: Создание пользователя deploy
ansible.builtin.user:
name: deploy
shell: /bin/bash
create_home: true
state: present
Добавим его в группу sudo:
- name: Добавление deploy в группу sudo
ansible.builtin.user:
name: deploy
groups: sudo
append: true
При необходимости устанавливаем сам sudo:
- name: Установка sudo
ansible.builtin.apt:
name: sudo
state: present
Добавление SSH-ключа
Для входа под deploy используем SSH-ключ.
В начале Playbook можно определить переменную:
vars:
ssh_public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... user@pc"
Затем добавить ключ:
- name: Добавление SSH-ключа
ansible.posix.authorized_key:
user: deploy
state: present
key: "{{ ssh_public_key }}"
Если коллекция ansible.posix еще не установлена:
ansible-galaxy collection install ansible.posix
Настройка sudo
Создадим отдельное правило:
- name: Создание каталога sudoers.d
ansible.builtin.file:
path: /etc/sudoers.d
state: directory
owner: root
group: root
mode: '0755'
- name: Разрешение sudo без пароля
ansible.builtin.copy:
dest: /etc/sudoers.d/deploy
content: "deploy ALL=(ALL) NOPASSWD: ALL\n"
owner: root
group: root
mode: '0440'
Теперь пользователь deploy сможет выполнять административные команды через sudo.
Например:
sudo systemctl restart nginx
Настройка SSH
После того как пользователь и SSH-ключ созданы, можно отключить небезопасные варианты входа.
Запретим SSH-вход под root:
- name: Запрет входа root через SSH
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin no'
validate: '/usr/sbin/sshd -t -f %s'
notify: Перезапуск SSH
Отключим авторизацию по паролю:
- name: Отключение авторизации по паролю
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PasswordAuthentication'
line: 'PasswordAuthentication no'
validate: '/usr/sbin/sshd -t -f %s'
notify: Перезапуск SSH
Handler:
handlers:
- name: Перезапуск SSH
ansible.builtin.service:
name: ssh
state: restarted
Как и в предыдущей статье, обязательно проверяем новый SSH-доступ до закрытия текущего root-сеанса.
Настройка hostname
Для нескольких серверов полезно задать понятные имена.
В Inventory можно добавить:
[servers]
server1 ansible_host=192.168.88.40 hostname=web-01
server2 ansible_host=192.168.88.41 hostname=web-02
server3 ansible_host=192.168.88.42 hostname=web-03
А в Playbook:
- name: Настройка hostname
ansible.builtin.hostname:
name: "{{ hostname }}"
Теперь каждый сервер получит собственное имя.
Проверить его можно:
hostnamectl
Полный Playbook
Теперь объединим всё в один сценарий.
---
- name: Первоначальная настройка Linux-серверов
hosts: servers
vars:
ssh_public_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... user@pc"
tasks:
- name: Обновление списка пакетов
ansible.builtin.apt:
update_cache: true
- name: Установка базовых пакетов
ansible.builtin.apt:
name:
- curl
- wget
- vim
- htop
- unzip
- ca-certificates
- sudo
state: present
- name: Настройка часового пояса
community.general.timezone:
name: Europe/Moscow
- name: Установка systemd-timesyncd
ansible.builtin.apt:
name: systemd-timesyncd
state: present
- name: Запуск синхронизации времени
ansible.builtin.service:
name: systemd-timesyncd
state: started
enabled: true
- name: Настройка hostname
ansible.builtin.hostname:
name: "{{ hostname }}"
- name: Создание пользователя deploy
ansible.builtin.user:
name: deploy
shell: /bin/bash
create_home: true
state: present
- name: Добавление deploy в группу sudo
ansible.builtin.user:
name: deploy
groups: sudo
append: true
- name: Добавление SSH-ключа
ansible.posix.authorized_key:
user: deploy
state: present
key: "{{ ssh_public_key }}"
- name: Создание каталога sudoers.d
ansible.builtin.file:
path: /etc/sudoers.d
state: directory
owner: root
group: root
mode: '0755'
- name: Разрешение sudo без пароля
ansible.builtin.copy:
dest: /etc/sudoers.d/deploy
content: "deploy ALL=(ALL) NOPASSWD: ALL\n"
owner: root
group: root
mode: '0440'
- name: Запрет входа root через SSH
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin no'
validate: '/usr/sbin/sshd -t -f %s'
notify: Перезапуск SSH
- name: Отключение авторизации по паролю
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PasswordAuthentication'
line: 'PasswordAuthentication no'
validate: '/usr/sbin/sshd -t -f %s'
notify: Перезапуск SSH
handlers:
- name: Перезапуск SSH
ansible.builtin.service:
name: ssh
state: restarted
Inventory с индивидуальными hostname
Для полного примера Inventory будет выглядеть так:
[servers]
server1 ansible_host=192.168.88.40 hostname=web-01
server2 ansible_host=192.168.88.41 hostname=web-02
server3 ansible_host=192.168.88.42 hostname=web-03
Теперь один и тот же Playbook можно применить сразу к трем серверам.
Установка необходимых коллекций
Перед запуском убедимся, что установлены используемые коллекции:
ansible-galaxy collection install ansible.posix community.general
Проверить установленные коллекции:
ansible-galaxy collection list
Проверка Playbook
Перед реальным запуском сначала проверяем синтаксис:
ansible-playbook -i inventory bootstrap.yml --syntax-check
Если ошибок нет, можно выполнить проверку в режиме --check:
ansible-playbook -i inventory bootstrap.yml -u root --check
И только после этого выполнить реальные изменения:
ansible-playbook -i inventory bootstrap.yml -u root
Что произойдет при запуске
Ansible пройдет по каждому серверу из группы servers.
Например:
server1
server2
server3
На каждом сервере будут выполнены одинаковые действия:
-
Обновится индекс пакетов.
-
Установятся необходимые утилиты.
-
Настроится часовой пояс.
-
Запустится синхронизация времени.
-
Изменится hostname.
-
Создастся пользователь
deploy. -
Пользователь получит SSH-ключ.
-
Настроится
sudo. -
Будет изменена конфигурация SSH.
-
SSH перезапустится только при необходимости.
В результате три новых сервера будут приведены к одному базовому состоянию.
Проверка результата
После завершения Playbook можно проверить серверы обычными командами.
Hostname:
hostnamectl
Пользователь:
id deploy
Часовой пояс:
timedatectl
Состояние времени:
timedatectl status
Проверка sudo:
sudo whoami
SSH:
ssh deploy@192.168.88.40
Повторный запуск
Попробуем запустить Playbook еще раз:
ansible-playbook -i inventory bootstrap.yml -u root
Если серверы уже находятся в нужном состоянии, большая часть задач должна завершиться со статусом:
ok
а не:
changed
Это особенно важно при массовой настройке.
Playbook можно запускать повторно после добавления нового сервера в Inventory - Ansible применит необходимые изменения только к нему.
Почему это удобно
Представим, что сегодня необходимо подготовить три сервера, завтра - еще пять, а через месяц - еще десять.
Вместо ручного выполнения десятков команд достаточно добавить новые серверы в Inventory:
[servers]
server1 ansible_host=192.168.88.40 hostname=web-01
server2 ansible_host=192.168.88.41 hostname=web-02
server3 ansible_host=192.168.88.42 hostname=web-03
server4 ansible_host=192.168.88.43 hostname=web-04
server5 ansible_host=192.168.88.44 hostname=web-05
и снова запустить тот же Playbook. Ansible самостоятельно подготовит новые серверы. При этом конфигурация остается описанной в одном месте и не зависит от того, сколько серверов необходимо настроить.
Заключение
В этой статье мы собрали единый Playbook для первоначальной подготовки нескольких Linux-серверов.
Теперь вместо ручной настройки каждого нового сервера можно добавить его в Inventory и запустить один сценарий. Ansible установит необходимые пакеты, настроит время и hostname, создаст административного пользователя, добавит SSH-ключ и приведет SSH-конфигурацию к заданному состоянию.
В следующей статье рассмотрим AWX: установим веб-интерфейс для управления Ansible, подключим Git-репозиторий и научимся запускать Playbook через браузер.





