Примеры ролей 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: dmosk
  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
  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

* в данном примере мы:

  1. Создаем пользователя prometheus.
  2. Создаем каталоги, в которые будут помещены файлы сервиса.
  3. Скачиваем и распаковываем архив прометея с официального сайта.
  4. Копируем бинарники.
  5. Копируем конфигурационные файлы.
  6. Создаем юнит в systemd.
  7. Стартуем сервис.

Создаем 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

* в данном примере мы:

  1. Создаем пользователя alertmanager.
  2. Создаем каталоги, в которые будут помещены файлы сервиса.
  3. Скачиваем и распаковываем архив alertmanager с официального сайта.
  4. Копируем бинарники.
  5. Копируем конфигурационные файлы.
  6. Создаем юнит в systemd.
  7. Стартуем сервис.

Создаем файл в шаблонах с юнитом 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: dmosk
  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

    - 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 задания:

  1. Перезапуск брандмауэра firewalld для применения настроек.
  2. Разрешение автозапуска сервиса grafana.

Создаем файл для плейбука:

vi start_role.yml

---

- hosts: test_servers
  user: dmosk
  become: true
  become_method: su
  become_user: root
  roles:
    - Grafana

* в данном примере мы запускаем выполнение роли Grafana на серверы из группы test_servers.

Запускаем созданный плейбук:

ansible-playbook start_role.yml -kK

# Управление # Серверы # Linux # DevOps
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет