Примеры настройки сервисов и их установки с помощью ролей в Ansible
Используемые термины: Ansible, Bind, Prometheus, Grafana.
Мы рассмотрим простые примеры установки различных систем с помощью ролей Ansible. Инструкция больше имеет практическое применение с минимальным количеством пояснений и комментариев, но хорошо подойдет в качестве шпаргалки.
Подготовка к работе
Предполагается, что у нас уже есть сервер с установленным Ansible, например, по инструкции Установка и запуск Ansible на CentOS.
В файл hosts мы должны добавить серверы, на которые будем устанавливать наши сервисы:
vi /etc/ansible/hosts
[test_servers]
192.168.1.115
192.168.1.116
* в моем примере мы добавили тестовую группу test_servers, а в нее 2 сервера.
Мы будем работать относительно каталога с ролями, поэтому сделаем переход в него:
cd /etc/ansible/roles/
Можно приступать к созданию ролей.
Синтаксис и описание
Пару слов о том, как будем работать.
Каждую роль мы создаем с помощью команды ansible-galaxy. Синтаксис следующий:
ansible-galaxy init <Имя роли>
После ввода команды в текущем каталоге (в нашем примере, /etc/ansible/roles) будет создана папка с названием роли, а в ней следующая структура каталогов:
- defaults — переменные по умолчанию. У них самый низкий приоритет и их могут легко переопределить переменные в каталоге vars (ниже по списку).
- files — для файлов, которые могут быть скопированы на настраиваемый сервер.
- handlers — обработчики, которые могут запускаться при определенных обстоятельствах. Например, перезапуск сервиса в случае обновления конфигурационного файла.
- meta — добавление метаданных, например: автор, описание, среда и так далее.
- tasks — папка с описанием выполняемых задач.
- templates — файлы с шаблонами. Мы можем использовать переменные в данных шаблонах — тогда при копировании файлов, они будут заменяться значениями.
- tests — скрипты для выполнения тестов — ansible покажет результаты выполнения команд, но не применит их.
- vars — файлы с переменными. Имеют высокий приоритет.
После будем приступать к настройке роли, созданию и запуску плейбука.
NGINX
Установке и настройке NGINX с помощью Ansible я посвятил отдельную инструкцию.
Bind DNS
Инициализируем новую роль:
ansible-galaxy init Bind
* мы назвали нашу роль Bind.
Открываем основной файл для задачи:
vi Bind/tasks/main.yml
Добавляем:
—
— name: Include vars for os family
include_vars:
file: «{{ ansible_os_family }}.yml»
— name: Install Bind on RedHat Family
yum:
name: bind
state: present
when:
ansible_os_family == «RedHat»
notify:
— bind systemd
— name: Install Bind on Debian Family
apt:
name: «{{ item }}»
state: present
loop:
— bind9
— dnsutils
when:
ansible_os_family == «Debian»
notify:
— bind systemd
* в зависимости от типа операционной системы мы подгрузим разные переменные (так как в разных системах имя для bind разное), после чего устанавливаем bind с помощью yum (для систем на базе Red Hat) или apt (Debian). Обратите внимание, что для систем Debian мы выполняем установку двух пакетов, для перечисления которых используем цикл.
Создаем файл с переменными для debian:
vi Bind/vars/Debian.yml
—
service_name : bind9
* с переменной service_name и значением bind9.
Также создаем файл с переменными в роли Bind для систем на базе Red Hat:
vi Bind/vars/RedHat.yml
—
service_name : named
* во втором файле значение для переменной service_name будет named.
Редактируем файл для handlers:
vi Bind/handlers/main.yml
—
— name: bind systemd
systemd:
name: «{{ service_name }}»
enabled: yes
state: started
* после установки bind необходимо разрешить автозапуск сервиса и стартовать его. Имя сервиса подставляется из переменной и зависит от типа операционной системы Linux.
Создаем файл для плейбука:
vi start_role.yml
—
— hosts: test_servers
user: admins24
become: true
become_method: su
become_user: root
roles:
— Bind
* в данном примере мы запускаем выполнение роли Bind на серверы из группы test_servers.
Запускаем созданный плейбук:
ansible-playbook start_role.yml -kK
Prometheus
Создаем файлы для роли, которую назовем Prometheus:
ansible-galaxy init Prometheus
Открываем на редактирование файл с заданиями:
vi Prometheus/tasks/main.yml
Логически, мы поделим задачи на 3 файла:
—
— name: Prepare For Install Prometheus
include_tasks: tasks/prepare.yml
— name: Install Prometheus
include_tasks: tasks/install_prometheus.yml
— name: Install Alertmanager
include_tasks: tasks/install_alertmanager.yml
* в первом файле будут описаны задачи для подготовки системы к установке Prometheus; во втором файле мы выполним установку системы мониторинга; в третьем файле описание для установки alertmanager.
Создаем первый файл с задачами:
vi Prometheus/tasks/prepare.yml
—
— name: Security Settings For RedHat
block:
— name: Allow Ports
firewalld:
port: «{{ item }}»
permanent: true
state: enabled
loop: [ ‘9090/tcp’, ‘9093/tcp’, ‘9094/tcp’, ‘9100/tcp’, ‘9094/udp’ ]
notify:
— firewalld systemd restart
— name: Disable SELinux
selinux:
state: disabled
— name: Stop SELinux
shell: setenforce 0
ignore_errors: yes
when:
ansible_os_family == «RedHat»
— name: Security Settings For Debian
block:
— name: Allow TCP Ports
iptables:
chain: INPUT
rule_num: ‘1’
action: insert
protocol: tcp
jump: ACCEPT
destination_port: «{{ item }}»
loop: [ ‘9090’, ‘9093’, ‘9094’, ‘9100’ ]
— name: Allow UDP Ports
iptables:
chain: INPUT
rule_num: ‘1’
action: insert
protocol: udp
jump: ACCEPT
destination_port: ‘9094’
when:
ansible_os_family == «Debian»
* в данном примере будут открыты в брандмауэре порты для корректной работы prometheus и alertmanager, а также будет отключен SELinux. Мы используем условие when, чтобы применить нужные команды, разделенные блоками (block), к нужному типу дистрибутива Linux, однако, если в вашей среде не используется брандмауэр или на CentOS применяется iptables, необходимо внести коррекции.
Открываем файл с переменными:
vi Prometheus/vars/main.yml
Создаем две:
—
prometheus_version : 2.23.0
alertmanager_version : 0.21.0
* данным переменным в качестве значения присваиваем версии prometheus и alertmanager, которые необходимо установить. В нашем примере взяты последние версии на момент обновления инструкции. Актуальные версии можно посмотреть на странице загрузки.
Создаем файл с описанием задач по установке Prometheus:
vi Prometheus/tasks/install_prometheus.yml
—
— name: Create User prometheus
user:
name: prometheus
create_home: no
shell: /bin/false
— name: Create directories for prometheus
file:
path: «{{ item }}»
state: directory
owner: prometheus
group: prometheus
loop:
— ‘/tmp/prometheus’
— ‘/etc/prometheus’
— ‘/var/lib/prometheus’
— name: Download And Unzipped Prometheus
unarchive:
src: https://github.com/prometheus/prometheus/releases/download/v{{ prometheus_version }}/prometheus-{{ prometheus_version }}.linux-amd64.tar.gz
dest: /tmp/prometheus
creates: /tmp/prometheus/prometheus-{{ prometheus_version }}.linux-amd64
remote_src: yes
— name: Copy Bin Files From Unzipped to Prometheus
copy:
src: /tmp/prometheus/prometheus-{{ prometheus_version }}.linux-amd64/{{ item }}
dest: /usr/local/bin/
remote_src: yes
mode: preserve
owner: prometheus
group: prometheus
loop: [ ‘prometheus’, ‘promtool’ ]
— name: Copy Conf Files From Unzipped to Prometheus
copy:
src: /tmp/prometheus/prometheus-{{ prometheus_version }}.linux-amd64/{{ item }}
dest: /etc/prometheus/
remote_src: yes
mode: preserve
owner: prometheus
group: prometheus
loop: [ ‘console_libraries’, ‘consoles’, ‘prometheus.yml’ ]
— name: Create File for Prometheus Systemd
template:
src=templates/prometheus.service
dest=/etc/systemd/system/
notify:
— systemd reload
— name: Systemctl Prometheus Start
systemd:
name: prometheus
state: started
enabled: yes
* в данном примере мы:
- Создаем пользователя prometheus.
- Создаем каталоги, в которые будут помещены файлы сервиса.
- Скачиваем и распаковываем архив прометея с официального сайта.
- Копируем бинарники.
- Копируем конфигурационные файлы.
- Создаем юнит в systemd.
- Стартуем сервис.
Создаем yml-файл с задачами по установке и запуску alertmanager:
vi Prometheus/tasks/install_alertmanager.yml
—
— name: Create User Alertmanager
user:
name: alertmanager
create_home: no
shell: /bin/false
— name: Create Directories For Alertmanager
file:
path: «{{ item }}»
state: directory
owner: alertmanager
group: alertmanager
loop:
— ‘/tmp/alertmanager’
— ‘/etc/alertmanager’
— ‘/var/lib/prometheus/alertmanager’
— name: Download And Unzipped Alertmanager
unarchive:
src: https://github.com/prometheus/alertmanager/releases/download/v{{ alertmanager_version }}/alertmanager-{{ alertmanager_version }}.linux-amd64.tar.gz
dest: /tmp/alertmanager
creates: /tmp/alertmanager/alertmanager-{{ alertmanager_version }}.linux-amd64
remote_src: yes
— name: Copy Bin Files From Unzipped to Alertmanager
copy:
src: /tmp/alertmanager/alertmanager-{{ alertmanager_version }}.linux-amd64/{{ item }}
dest: /usr/local/bin/
remote_src: yes
mode: preserve
owner: alertmanager
group: alertmanager
loop: [ ‘alertmanager’, ‘amtool’ ]
— name: Copy Conf File From Unzipped to Alertmanager
copy:
src: /tmp/alertmanager/alertmanager-{{ alertmanager_version }}.linux-amd64/alertmanager.yml
dest: /etc/alertmanager/
remote_src: yes
mode: preserve
owner: alertmanager
group: alertmanager
— name: Create File for Alertmanager Systemd
template:
src=templates/alertmanager.service
dest=/etc/systemd/system/
notify:
— systemd reload
— name: Systemctl Alertmanager Start
systemd:
name: alertmanager
state: started
enabled: yes
* в данном примере мы:
- Создаем пользователя alertmanager.
- Создаем каталоги, в которые будут помещены файлы сервиса.
- Скачиваем и распаковываем архив alertmanager с официального сайта.
- Копируем бинарники.
- Копируем конфигурационные файлы.
- Создаем юнит в systemd.
- Стартуем сервис.
Создаем файл в шаблонах с юнитом systemd для prometheus:
vi Prometheus/templates/prometheus.service
[Unit]
Description=Prometheus Service
After=network.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus
—config.file /etc/prometheus/prometheus.yml
—storage.tsdb.path /var/lib/prometheus/
—web.console.templates=/etc/prometheus/consoles
—web.console.libraries=/etc/prometheus/console_libraries
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
Создаем файл в шаблонах с юнитом systemd для alertmanager:
vi Prometheus/templates/alertmanager.service
[Unit]
Description=Alertmanager Service
After=network.target
[Service]
EnvironmentFile=-/etc/default/alertmanager
User=alertmanager
Group=alertmanager
Type=simple
ExecStart=/usr/local/bin/alertmanager
—config.file=/etc/alertmanager/alertmanager.yml
—storage.path=/var/lib/prometheus/alertmanager
$ALERTMANAGER_OPTS
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
Открываем на редактирование файл с обработчиками:
vi Prometheus/handlers/main.yml
Приводим его к виду:
—
— name: firewalld systemd restart
systemd:
name: firewalld
state: reloaded
— name: systemd reload
systemd:
daemon_reload: yes
* в данном примере мы будем перезапускать firewalld и перечитывать юниты в systemd.
Создаем плейбук:
vi start_role.yml
—
— hosts: test_servers
user: admins24
become: true
become_method: su
become_user: root
roles:
— role: Prometheus
tags: prom
* данный файл описывает плейбук для запуска роли Prometheus. Обратите внимание, что для примера мы добавили тег prom.
Запускаем наш плейбук для установки Prometheus + Alertmanager:
ansible-playbook —tags prom start_role.yml -kK
* в данном примере запуск вложенной роли запускается с тегом prom. Это ни на что не влияет, но, если бы у нас в плейбуке будет много ролей, с помощью тега мы можем запускать конкретную.
Grafana
Инициализируем файлы для роли Grafana:
ansible-galaxy init Grafana
Открываем на редактирование файл с заданиями:
vi Grafana/tasks/main.yml
Установка будет учитывать системы типа Debian или Red Hat с помощью блоков:
— name: Security Settings For RedHat
block:
— name: Allow Ports
firewalld:
port: ‘3000/tcp’
permanent: true
state: enabled
notify:
— firewalld systemd restart
— name: Disable SELinux
selinux:
state: disabled
— name: Stop SELinux
shell: setenforce 0
ignore_errors: yes
— name: Add Repository
yum_repository:
name: Grafana
description: Grafana YUM repo
baseurl: https://packages.grafana.com/oss/rpm
gpgkey: https://packages.grafana.com/gpg.key
gpgcheck: yes
sslverify: yes
sslcacert: /etc/pki/tls/certs/ca-bundle.crt
— name: Install Grafana on RedHat Family
yum:
name: grafana
state: present
notify:
— grafana systemd
when:
ansible_os_family == «RedHat»
— name: Security Settings For Debian
block:
— name: Allow TCP Ports
iptables:
chain: INPUT
rule_num: ‘1’
action: insert
protocol: tcp
jump: ACCEPT
destination_port: ‘3000’
— name: Import Grafana Apt Key
apt_key:
url: https://packages.grafana.com/gpg.key
state: present
— name: Add APT Repository
apt_repository:
repo: deb https://packages.grafana.com/oss/deb stable main
state: present
— name: Install Grafana on Debian Family
apt:
name: grafana
state: present
notify:
— grafana systemd
when:
ansible_os_family == «Debian»
* в нашем примере мы независимо от системы создаем правило в брандмауэре для порта 3000, добавляем репозиторий, устанавливаем графану.
Редактируем файл для handlers:
vi Grafana/handlers/main.yml
—
— name: firewalld systemd restart
systemd:
name: firewalld
state: reloaded
— name: grafana systemd
systemd:
name: grafana-server
enabled: yes
state: started
* в нашем handlers есть 2 задания:
- Перезапуск брандмауэра firewalld для применения настроек.
- Разрешение автозапуска сервиса grafana.
Создаем файл для плейбука:
vi start_role.yml
—
— hosts: test_servers
user: admins24
become: true
become_method: su
become_user: root
roles:
— Grafana
* в данном примере мы запускаем выполнение роли Grafana на серверы из группы test_servers.
Запускаем созданный плейбук:
ansible-playbook start_role.yml -kK