Автоматизация серверов с Ansible: Infrastructure as Code
Установка Ansible, файл инвентаря, написание playbook, структура ролей, переменные, зашифрованный vault, ad-hoc команды и автоматизация конфигурации серверов. Пошаговое руководство.
Содержание
Автоматизация серверов с Ansible: Infrastructure as Code
Ansible — инструмент с открытым исходным кодом, позволяющий управлять конфигурацией серверов, развёртыванием приложений и автоматизацией задач как кодом. Благодаря безагентной архитектуре он подключается к целевым серверам только по SSH.
Что такое Ansible?
Ключевые особенности Ansible:
- Безагентный: Не требует установки дополнительного ПО на целевых серверах
- Идемпотентный: Многократный запуск одного playbook даёт одинаковый результат
- На основе YAML: Легко читать и писать
- Большая библиотека модулей: 3000+ готовых модулей
Ansible подключается с управляющего узла к целевым серверам по SSH. Для Windows-серверов используется WinRM.
Установка Ansible
Ubuntu/Debian
# Добавить PPA-репозиторий
sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible -y
# Проверить версию
ansible --version
RHEL/CentOS/AlmaLinux
# Добавить EPEL-репозиторий
sudo dnf install epel-release -y
sudo dnf install ansible -y
# Альтернатива: установить через pip
pip3 install ansible
Установка через pip (Рекомендуется)
# Создать виртуальное окружение Python
python3 -m venv ansible-env
source ansible-env/bin/activate
# Установить Ansible и дополнительные инструменты
pip install ansible ansible-lint
# Проверить версию
ansible --version
Файл инвентаря
Инвентарь определяет серверы, которыми будет управлять Ansible:
Формат INI
# /etc/ansible/hosts или пользовательский файл инвентаря
# Одиночный сервер
web1.example.com
# Определение группы
[webservers]
web1.example.com
web2.example.com ansible_port=2222
192.168.1.10 ansible_user=ubuntu
[databases]
db1.example.com
db2.example.com
# Переменные группы
[webservers:vars]
ansible_user=deploy
ansible_python_interpreter=/usr/bin/python3
# Родительская группа
[production:children]
webservers
databases
Формат YAML
# inventory.yml
all:
children:
webservers:
hosts:
web1.example.com:
ansible_port: 22
web2.example.com:
ansible_port: 2222
vars:
ansible_user: deploy
http_port: 80
databases:
hosts:
db1.example.com:
db2.example.com:
vars:
ansible_user: dbadmin
db_port: 5432
Ad-hoc команды
Выполняйте команды без написания playbook для быстрых задач:
# Тест ping
ansible all -m ping
ansible webservers -m ping -i inventory.yml
# Выполнить команду
ansible all -m command -a "uptime"
ansible webservers -m shell -a "df -h"
# Скопировать файл
ansible webservers -m copy -a "src=/local/file dest=/remote/path"
# Установить пакет
ansible webservers -m apt -a "name=nginx state=present" --become
# Управление сервисом
ansible webservers -m service -a "name=nginx state=started enabled=yes" --become
# Создать/удалить файл
ansible all -m file -a "path=/tmp/test state=touch"
ansible all -m file -a "path=/tmp/test state=absent"
# Собрать факты
ansible web1.example.com -m setup
ansible all -m setup -a "filter=ansible_os_family"
Написание Playbook
Базовая структура Playbook
# site.yml
---
- name: Настройка веб-серверов
hosts: webservers
become: yes # использовать sudo
vars:
http_port: 80
max_clients: 200
tasks:
- name: Установить Nginx
apt:
name: nginx
state: present
update_cache: yes
- name: Скопировать конфигурацию Nginx
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
notify: Перезапустить Nginx
- name: Запустить сервис Nginx
service:
name: nginx
state: started
enabled: yes
handlers:
- name: Перезапустить Nginx
service:
name: nginx
state: restarted
Tasks, Handlers и Roles
# Условные задачи
- name: Установить пакет на Ubuntu
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- curl
- git
when: ansible_os_family == "Debian"
- name: Установить пакет на RHEL
dnf:
name: "{{ item }}"
state: present
loop:
- nginx
- curl
- git
when: ansible_os_family == "RedHat"
# Создание пользователей в цикле
- name: Создать пользователей
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
state: present
loop:
- { name: 'alice', groups: 'sudo' }
- { name: 'bob', groups: 'www-data' }
# Регистрация и условие
- name: Проверить версию Nginx
command: nginx -v
register: nginx_version
ignore_errors: yes
- name: Установить Nginx если не установлен
apt:
name: nginx
state: present
when: nginx_version.rc != 0
Переменные и факты
# group_vars/webservers.yml
http_port: 80
https_port: 443
app_user: www-data
app_dir: /var/www/html
# host_vars/web1.example.com.yml
ansible_host: 192.168.1.10
server_name: web1.example.com
# Использование переменных в playbook
- name: Создать директорию приложения
file:
path: "{{ app_dir }}"
state: directory
owner: "{{ app_user }}"
mode: '0755'
# Использование фактов
- name: Показать информацию о системе
debug:
msg: |
ОС: {{ ansible_distribution }} {{ ansible_distribution_version }}
CPU: {{ ansible_processor_vcpus }} ядер
RAM: {{ ansible_memtotal_mb }} МБ
IP: {{ ansible_default_ipv4.address }}
Ansible Vault
Для шифрования конфиденциальных данных:
# Создать зашифрованный файл
ansible-vault create secrets.yml
# Зашифровать существующий файл
ansible-vault encrypt vars/passwords.yml
# Редактировать зашифрованный файл
ansible-vault edit secrets.yml
# Просмотреть зашифрованный файл
ansible-vault view secrets.yml
# Удалить шифрование
ansible-vault decrypt vars/passwords.yml
# Изменить пароль
ansible-vault rekey secrets.yml
# Запустить playbook с vault
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file ~/.vault_pass
Структура ролей
# Создать роль
ansible-galaxy init roles/nginx
# Структура директорий роли
roles/nginx/
├── defaults/
│ └── main.yml # Переменные по умолчанию
├── files/
│ └── nginx.conf # Статические файлы
├── handlers/
│ └── main.yml # Обработчики
├── meta/
│ └── main.yml # Метаданные роли
├── tasks/
│ └── main.yml # Основные задачи
├── templates/
│ └── vhost.conf.j2 # Шаблоны Jinja2
└── vars/
└── main.yml # Переменные
Примеры Playbook
Playbook установки Nginx
---
- name: Установка веб-сервера Nginx
hosts: webservers
become: yes
vars:
domain: example.com
web_root: /var/www/{{ domain }}
tasks:
- name: Установить Nginx
apt:
name: nginx
state: present
update_cache: yes
- name: Создать веб-директорию
file:
path: "{{ web_root }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Создать пример index.html
copy:
content: "<h1>Привет от {{ inventory_hostname }}</h1>"
dest: "{{ web_root }}/index.html"
owner: www-data
- name: Настроить виртуальный хост
template:
src: vhost.conf.j2
dest: /etc/nginx/sites-available/{{ domain }}
notify: Перезагрузить Nginx
- name: Включить виртуальный хост
file:
src: /etc/nginx/sites-available/{{ domain }}
dest: /etc/nginx/sites-enabled/{{ domain }}
state: link
notify: Перезагрузить Nginx
- name: Отключить сайт по умолчанию
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: Перезагрузить Nginx
- name: Разрешить Nginx в UFW
ufw:
rule: allow
name: 'Nginx Full'
handlers:
- name: Перезагрузить Nginx
service:
name: nginx
state: reloaded
Запуск Playbook
# Базовый запуск
ansible-playbook site.yml
# С конкретным инвентарём
ansible-playbook -i inventory.yml site.yml
# Конкретный хост или группа
ansible-playbook site.yml --limit webservers
ansible-playbook site.yml --limit web1.example.com
# Dry-run (проверка без изменений)
ansible-playbook site.yml --check
# Подробный режим
ansible-playbook site.yml -v
ansible-playbook site.yml -vvv
# Запустить конкретные теги
ansible-playbook site.yml --tags "nginx,ssl"
ansible-playbook site.yml --skip-tags "debug"
# Дополнительные переменные
ansible-playbook site.yml -e "env=production version=1.5"
Заключение
Ansible — один из наиболее доступных способов управления автоматизацией серверов как кодом. Благодаря безагентной архитектуре, большой библиотеке модулей и структуре на основе YAML вы можете легко управлять как небольшой, так и крупной инфраструктурой. Храните конфиденциальные данные в безопасности с Vault, создавая повторно используемые конфигурации с ролями.
Связанные статьи
Руководство по Docker Compose: Управление многоконтейнерными приложениями
Определение и управление многоконтейнерными приложениями с Docker Compose: зависимости сервисов, переменные окружения, проверки работоспособности, масштабирование и развёртывание в production. Полное руководство.
Автоматическое развёртывание с GitHub Actions: настройка CI/CD Pipeline
Создание CI/CD-пайплайнов с GitHub Actions: сборка и публикация Docker, развёртывание на сервере по SSH, автоматизация тестов, управление секретами и оптимизация рабочих процессов.
Настройка веб-сервера Caddy: автоматический HTTPS и обратный прокси
Установка веб-сервера Caddy, настройка Caddyfile, автоматический SSL от Let's Encrypt, обратный прокси, хостинг статических сайтов, интеграция PHP-FPM и настройки производительности.