Categories: Шпаргалки

Примеры ролей 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 сервера.

Мы будем работать относительно каталога с ролями, поэтому создадим его и перейдем в созданную директорию:

mkdir /etc/ansible/roles

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: remontka
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

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

  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
command: firewall-cmd —reload

— name: systemd reload
systemd:
daemon_reload: yes

* в данном примере мы будем перезапускать firewalld и перечитывать юниты в systemd.

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

vi start_role.yml

— hosts: test_servers
user: remontka
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 And Install Grafana 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 And Install Grafana 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
command: firewall-cmd —reload

— 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: remontka
become: true
become_method: su
become_user: root
roles:
— Grafana

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

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

ansible-playbook start_role.yml -kK

Hasicorp Vault

Подробнее об установке и настройке Hashicorp Vault .

Инициализируем файлы для роли Vault:

ansible-galaxy init Vault

Открываем на редактирование файл с заданиями:

vi Vault/tasks/main.yml

Разделим наше задание на два этапа — преднастройку системы и установку Vault:

— name: Prepare System
include_tasks: tasks/prepare.yml

— name: Install Vault
include_tasks: tasks/install_vault.yml

Создаем файл с задачами для преднастройки системы:

vi Vault/tasks/prepare.yml

— name: Prepare System For RedHat
block:
— name: Install Packages
yum:
name: «{{ item }}»
state: present
loop:
— wget
— chrony
— curl
— name: Allow Ports
firewalld:
port: «{{ item }}»
permanent: true
state: enabled
immediate: yes
loop: [ ‘8200/tcp’ ]
when:
ansible_os_family == «RedHat»

— name: Security Settings For Debian
block:
— name: Install Packages
apt:
name: «{{ item }}»
state: present
update_cache: yes
loop:
— wget
— chrony
— curl
— apt-transport-https
— iptables-persistent
— name: Allow TCP Ports
iptables:
chain: INPUT
rule_num: ‘1’
action: insert
protocol: tcp
jump: ACCEPT
destination_port: «{{ item }}»
loop: [ ‘8200’ ]
notify:
— iptables save
when:
ansible_os_family == «Debian»

Теперь создаем файл с заданиями по установке Vault:

vi Vault/tasks/install_vault.yml

— name: Install Hashicorp Vault For RedHat
block:
— name: Add Repository
get_url:
url: https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
dest: /etc/yum.repos.d/hashicorp.repo
— name: Install Vault
yum:
name: vault
state: present
notify:
— vault systemd
— name: Set Shell Enviroment
copy:
src: profile.d/vault.sh
dest: /etc/profile.d/vault.sh
when:
ansible_os_family == «RedHat»

— name: Install Hashicorp Vault For Debian
block:
— name: Import Vault Apt Key
apt_key:
url: https://apt.releases.hashicorp.com/gpg
state: present
— name: Add APT Repository
apt_repository:
repo: deb [arch=amd64] https://apt.releases.hashicorp.com {{ ansible_lsb.codename }} main
state: present
filename: hashicorp
— name: Install Vault
apt:
name: vault
state: present
notify:
— vault systemd
— name: Set Shell Enviroment
lineinfile:
path: /etc/environment
line: export VAULT_SKIP_VERIFY=true
create: yes
when:
ansible_os_family == «Debian»

Создаем хендлер для сохранения правил iptables и настройки сервиса vault:

vi Vault/handlers/main.yml

— name: iptables save
shell: netfilter-persistent save

— name: vault systemd
systemd:
name: «vault»
enabled: yes
state: started

Создаем каталог:

mkdir Vault/files/profile.d

Создадим в нем файл для настройки среды окружения для CentOS:

vi Vault/files/profile.d/vault.sh

export VAULT_SKIP_VERIFY=true

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

vi start_role.yml

— hosts: test_servers
user: remontka
become: true
become_method: su
become_user: root
roles:
— Vault

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

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

ansible-playbook start_role.yml -kK

Кластер Kubernetes

В нашем примере мы создадим сценарий для настройки кластера под управлением Ubuntu Server. Подробнее о настройке Kubernetes на Ubuntu .

Для описания нод кластера мы будем использовать отдельный inventory файл:

mkdir /etc/ansible/inventory

vi /etc/ansible/inventory/kube_servers.yml

kube_servers:
vars:
ansible_python_interpreter: /usr/bin/python3
hosts:
server01:
ansible_host: master.remontka.local
ansible_ssh_host: 192.168.100.12
server02:
ansible_host: worker01.remontka.local
ansible_ssh_host: 192.168.100.13
server03:
ansible_host: worker02.remontka.local
ansible_ssh_host: 192.168.100.14

children:
master:
hosts:
server01:
worker:
hosts:
server02:
server03:

* в нашем примере установка будет выполнена на три сервера — один мастер и два воркера. Также мы выделили 2 группы — master и worker в которые вошли соответствующие серверы. Такая инвентаризация позволит нам точно указать, какие серверы мы планируем использовать в качестве мастера, а какие в качестве рабочих нод.

Инициализируем роль:

ansible-galaxy init Kubernetes

Откроем файл с задачами:

vi Kubernetes/tasks/main.yml

Пропишем следующее:

— name: Set hostname
hostname:
name: «{{ hostvars[inventory_hostname].ansible_host }}»

— name: Add to hosts file cluster machines
blockinfile:
path: /etc/hosts
block: |
{% for host in groups[‘kube_servers’] %}
{{ hostvars[host].ansible_ssh_host }} {{ hostvars[host].ansible_host }}
{% endfor %}

— name: Disable SWAP 1/2 (swapoff)
shell: swapoff -a

— name: Disable SWAP 2/2 (fstab)
replace:
path: /etc/fstab
regexp: ‘^([^#].*?sswaps+sws+.*)$’
replace: ‘# 1’

— name: Create File for modules load
file:
path: /etc/modules-load.d/k8s.conf
state: touch
owner: root
group: root
mode: 0644

— name: Add modules k8s
lineinfile:
path: /etc/modules-load.d/k8s.conf
line: «{{ item }}»
loop:
— br_netfilter
— overlay

— name: Add br_netfilter and overlay modules
modprobe:
name: «{{ item }}»
state: present
loop:
— br_netfilter
— overlay

— name: Set sysctl bridge-nf-call options
sysctl:
name: «{{ item }}»
value: ‘1’
state: present
reload: yes
sysctl_file: /etc/sysctl.d/k8s.conf
loop:
— net.bridge.bridge-nf-call-ip6tables
— net.bridge.bridge-nf-call-iptables

— name: Docker install
package:
name:
— docker
— docker.io
state: present

— name: Copy daemon.json config file
copy:
src: daemon.json
dest: /etc/docker/daemon.json
remote_src: no
mode: 0644
owner: root
group: root

— name: Docker systemctl enable and start
systemd:
name: docker
enabled: yes
state: restarted

— name: Import kubernetes repo key
apt_key:
url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
state: present

— name: «Add kubernetes repository»
apt_repository:
repo: deb https://apt.kubernetes.io/ kubernetes-xenial main
filename: kubernetes

— name: kubernetes install
apt:
name:
— kubelet
— kubeadm
— kubectl
state: present
update_cache: yes

— name: Hold kubernetes to update
dpkg_selections:
name: «{{ item }}»
selection: hold
loop:
— kubelet
— kubeadm
— kubectl

— name: Master Settings
block:

— name: kubeadm init pod-network-cidr
shell: kubeadm init —pod-network-cidr=10.244.0.0/16
ignore_errors: yes

— name: Set KUBECONFIG system environment permanently
lineinfile:
path: /etc/environment
line: export KUBECONFIG=/etc/kubernetes/admin.conf

— name: Install CNI (Container Networking Interface)
shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

— name: Get join command
shell: kubeadm token create —print-join-command
register: join_command

— name: Open ports on a firewall for Master
iptables:
action: insert
rule_num: 1
chain: INPUT
protocol: tcp
destination_port: «{{ item }}»
jump: ACCEPT
loop:
— «6443»
— «2379:2380»
— «10250:10252»

when: «‘master’ in group_names»

— name: Workers Settings
block:

— name: Open ports on a firewall for Worker
iptables:
action: insert
rule_num: 1
chain: INPUT
protocol: tcp
destination_port: «{{ item }}»
jump: ACCEPT
loop:
— «10250»
— «30000:32767»

— name: kubeadm init pod-network-cidr
shell: «{{ hostvars[groups[‘master’].0].join_command.stdout }}»
ignore_errors: yes

when: «‘worker’ in group_names»

-name: Install iptables-persistent
package:
name: iptables-persistent
state: present

— name: Save firewall rule
shell: netfilter-persistent save

Создаем конфигурационный файл daemon.json:

vi Kubernetes/files/daemon.json

{
«exec-opts»: [«native.cgroupdriver=systemd»],
«log-driver»: «json-file»,
«log-opts»: {
«max-size»: «100m»
},
«storage-driver»: «overlay2»,
«storage-opts»: [
«overlay2.override_kernel_check=true»
]
}

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

vi start_role.yml

— hosts: kube_servers
user: root
gather_facts: true
become: true
become_method: su
become_user: root

roles:
— Kubernetes

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

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

ansible-playbook -i /etc/ansible/inventory/test_servers.yml start_role.yml

* обратите внимание, что с помощью опции -i мы указываем путь до инвентарного файла, который создали специально для данного примера.

Сборка из исходников NGINX

Ранее была указана ссылка на страницу с описанием установки NGINX из пакетов при помощи Ansible. Но если нам нужно добавить дополнительный модуль, необходима сборка веб-сервера из исходников. Данный пример, в большей степени, можно использовать для сборки и других пакетов.

В нашем примере мы соберем NGINX и добавим в него модуль SPNEGO. Модуль может быть любым — главное, понять принцип.

Создаем новую роль с любым названием, например, Nginx_Make:

ansible-galaxy init Nginx_Make

Открываем файл с переменными:

vi Nginx_Make/vars/main.yml

nginx_ver : 1.19.3

* нам нужна одна переменная для указания конкретной версии NGINX, которую мы хотим установить.

Открываем на редактирование файл с заданиями:

vi Nginx_Make/tasks/main.yml

— name: Security Settings For RedHat
block:
— name: Allow Ports
firewalld:
port: ‘{{ item }}/tcp’
permanent: true
state: enabled
immediate: true
loop: [ ’80’, ‘443’ ]
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: [ ’80’, ‘443’ ]
when:
ansible_os_family == «Debian»

— name: Installing NGINX Dependencies On Debian
apt:
name: «{{ item }}»
update_cache: yes
state: present
loop:
— git
— build-essential
— libpcre++-dev
— zlib1g-dev
— libkrb5-dev
— libssl-dev
— libxslt-dev
— libgd-dev
when:
ansible_os_family == «Debian»

— name: Installing NGINX Dependencies On Red Hat
yum:
name: «{{ item }}»
state: present
loop:
— epel-release
— git
— pcre-devel
— openssl-devel
— libxml2-devel
— libxslt-devel
— gd-devel
— perl-ExtUtils-Embed
— gperftools-devel
when:
ansible_os_family == «RedHat»

— name: Unpacking Nginx Source
unarchive:
src: «http://nginx.org/download/nginx-{{ nginx_ver }}.tar.gz»
dest: /tmp/
remote_src: yes
creates: /tmp/nginx-{{ nginx_ver }}.tar.gz
register: nginx_source_unpack

— name: Clone Nginx Module From GitHub
git:
repo: «https://github.com/stnoonan/spnego-http-auth-nginx-module.git»
dest: /tmp/nginx-{{ nginx_ver }}/spnego-http-auth-nginx-module
register: module_source_clone

— name: Configuring NGINX Source With Custom Modules For Debian
command: «./configure —prefix=/usr/share/nginx —sbin-path=/usr/sbin/nginx —conf-path=/etc/nginx/nginx.conf —http-log-path=/var/log/nginx/access.log —error-log-path=/var/log/nginx/error.log —lock-path=/var/lock/nginx.lock —pid-path=/run/nginx.pid —modules-path=/usr/lib/nginx/modules —http-client-body-temp-path=/var/lib/nginx/body —http-fastcgi-temp-path=/var/lib/nginx/fastcgi —http-proxy-temp-path=/var/lib/nginx/proxy —http-scgi-temp-path=/var/lib/nginx/scgi —http-uwsgi-temp-path=/var/lib/nginx/uwsgi —with-debug —with-compat —with-pcre-jit —with-http_ssl_module —with-http_stub_status_module —with-http_realip_module —with-http_auth_request_module —with-http_v2_module —with-http_dav_module —with-http_slice_module —with-threads —with-http_addition_module —with-http_gunzip_module —with-http_gzip_static_module —with-http_image_filter_module=dynamic —with-http_sub_module —with-http_xslt_module=dynamic —with-stream=dynamic —with-stream_ssl_module —with-mail=dynamic —with-mail_ssl_module —add-module=spnego-http-auth-nginx-module»
args:
chdir: «/tmp/nginx-{{ nginx_ver }}»
when: nginx_source_unpack.changed or module_source_clone.changed
register: nginx_configure

— name: Installing NGINX
shell: make && make install
args:
chdir: «/tmp/nginx-{{ nginx_ver }}»
when: nginx_configure.changed
register: installed_nginx

— name: Create Nginx User For Red Hat
user:
name: nginx
create_home: no
shell: /bin/false
when:
ansible_os_family == «RedHat»

— name: Create Folder /var/lib/nginx
file:
path: «/var/lib/nginx»
state: directory

— name: Create File for Nginx Systemd
copy:
src: files/nginx.service
dest: /lib/systemd/system
notify:
— systemd reload
register: create_nginx_systemd

— name: Systemctl Nginx Restart
systemd:
name: nginx
state: restarted
enabled: yes
when: create_nginx_systemd.changed or installed_nginx.changed

* обратите внимание:

  • необходимый набор зависимостей может оказаться индивидуальным, так как при добавлении других модулей система будет требовать других компонентов — лучшим решением будет собрать вручную nginx на тестовом сервере и определить точный набор пакетов для установки.
  • в данном примере для добавления модуля SPNEGO необходимо его клонировать с GitHub и разместить в каталоге с исходником. Для установки другого модуля могут понадобиться другие действия. Необходимо изучить документацию для каждого конкретного модуля.
  • опции конфигурирования индивидуальны и зависят от ваших потребностей. В данном примере используется общий набор опций.

Открываем файл для notify:

vi Nginx_Make/handlers/main.yml

— name: firewalld systemd restart
command: firewall-cmd —reload

— name: systemd reload
systemd:
daemon_reload: yes

Создаем файл для юнита systemd:

vi Nginx_Make/files/nginx.service

[Unit]
Description=A high performance web server and a reverse proxy server
Documentation=man:nginx(8)
After=network.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g ‘daemon on; master_process on;’
ExecStart=/usr/sbin/nginx -g ‘daemon on; master_process on;’
ExecReload=/usr/sbin/nginx -g ‘daemon on; master_process on;’ -s reload
ExecStop=-/sbin/start-stop-daemon —quiet —stop —retry QUIT/5 —pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed
Restart=on-failure

[Install]
WantedBy=multi-user.target

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

vi start_role.yml

— hosts: test_servers
user: remontka
become: true
become_method: su
become_user: root
roles:
— Nginx_Make

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

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

ansible-playbook start_role.yml -kK

Обновление сертификата

Так как большинство современных сервисов требуют для своей работы сертификат, рассмотрим пример централизованного их обновления.

Предположим, что у нас есть сертификат wildcard и необходимо его копировать на все серверы компании. Если серверов много, делать это вручную при очередном его обновлении неудобно.

И так, создаем новую роль:

ansible-galaxy init Update_Certs

Открываем на редактирование файл с заданиями:

vi Update_Certs/tasks/main.yml

— name: Register System Services
service_facts:
register: services_state

— name: Create Directories For Certs
file:
path: ‘/etc/ssl/dmoks’
state: directory
owner: root
group: root
mode: 0755

— name: Copy Cert File If Different
copy:
src: «{{ item }}»
dest: /etc/ssl/remontka
remote_src: no
mode: 0644
owner: root
group: root
with_fileglob:
— files/*
notify:
— reload httpd
— reload nginx
— reload apache2

* будут выполняться следующие задачи:

  • Register System Services — получаем список всех служб, которые работают на целевом компьютере
  • Create Directories For Certs — создаем каталог /etc/ssl/dmoks, в который будем копировать сертификаты
  • Copy Cert File If Different — копируем сертификаты в целевой каталог. Если были изменения в любом из файлов, по очереди запускаем 3 задачи в handlers для перезагрузки сервисов. Здесь нам нужно самостоятельно перечислить все службы, которые вам нужно перезагружать.

Открываем на редактирование файл в каталоге handlers:

vi Update_Certs/handlers/main.yml

Добавим строки:

— name: reload httpd
systemd:
name: httpd
state: restarted
when:
services_state.ansible_facts.services[‘httpd.service’].state == ‘running’
ignore_errors: yes

— name: reload nginx
systemd:
name: nginx
state: restarted
when:
services_state.ansible_facts.services[‘nginx.service’].state == ‘running’
ignore_errors: yes

— name: reload apache2
systemd:
name: apache2
state: restarted
when:
services_state.ansible_facts.services[‘apache2.service’].state == ‘running’
ignore_errors: yes

* в задачах, в случае изменения сертификатов, мы выполняем задания reload httpd , reload nginx и reload apache2 . Все задания описаны в данном файле. В данном примере мы проверяем, что сервисы запущены и если это так, перезапускаем их. Нам необходимо перезапускать все службы, которые используют сертификаты (в противном случае, обновленные сертификаты не будут использоваться). При необходимости дописать службы, делаем это по аналогии.

В каталог Update_Certs/files/ помещаем наши сертификаты — все содержимое данного каталога будет копироваться на целевые компьютеры в каталог /etc/ssl/remontka .

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

vi start_role.yml

— hosts: test_servers
user: remontka
become: true
become_method: su
become_user: root
roles:
— Update_Certs

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

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

ansible-playbook start_role.yml -kK

Создание пользователя

Это довольно типичная задача для возможности контролировать на своих серверах учетные записи пользователей. Рассмотрим пример централизованного создания нескольких аккаунтов. Подробная инструкция на официальном сайте .

И так, создаем новую роль:

ansible-galaxy init Local_Users

Предположим, мы создадим пользователей user1 и user2. Сгенерируем хэши для их паролей:

openssl passwd -salt ‘AnySalt’ -1

* где AnySalt — произвольный текст для соли.

После ввода команды система запросит ввести пароль — вводим и получаем хэш, например:

Password:
$1$AnySalt$J1MdB0X9KWZBg7BxeC9Ee0

Копируем его — он понадобиться позже. После повторяем команду, вводим новый пароль и генерируем хэш для второго пользователя.

Открываем на редактирование файл с заданиями:

vi Local_Users/tasks/main.yml

— name: Add User For Servers
user:
name: ‘{{ item.name }}’
password: ‘{{ item.password }}’
state: present
update_password: on_create
loop:
— { name: ‘user1’, password: ‘$1$AnySalt$J1MdB0X9KWZBg7BxeC9Ee0’ }
— { name: ‘user2’, password: ‘$1$AnySalt$It8oyh2yAISnUqI4jK5VR0’ }

* в данном примере будут созданы пользователи из цикла loop , в котором перечислены связки логин и пароль — конкретно, в нашем случае, это user1 и user2 ; state: present говорит, что пользователь должен присутствовать в системе; update_password: on_create установит наш пароль только при создании пользователя, ползволив ему самому сменить данные для аутентификации.

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

vi start_role.yml

— hosts: test_servers
user: remontka
become: true
become_method: su
become_user: root
roles:
— Local_Users

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

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

ansible-playbook start_role.yml -kK

admin

Recent Posts

Что такое Zulip

Zulip — программное обеспечение для реализации корпоративного чата. Разработан в 2012 году, в 2014 был…

2 месяца ago

Что такое Zookeeper

Zookeeper — cервис-координатор, который позволяет обеспечить контроль синхронизации данных. Разработан на Java компанией Apache Software…

2 месяца ago

Что такое Zimbra

Zimbra — программное обеспечение для реализации почтового сервиса или, если сказать точнее, автоматизации совместной деятельности…

2 месяца ago

Что такое Zabbix

Zabbix — бесплатная система мониторинга. Позволяет отслеживать состояние сетевых узлов, компьютеров и серверов. Возможности: Поддержка…

2 месяца ago

Что такое YouTube

YouTube — компания-владелец одноименного портала для просмотра и хранения видео. Чтобы пользоваться данным порталом достаточно…

2 месяца ago

Что такое yota

Yota — провайдер, предоставляющий доступ к сети Интернет по беспроводной связи. Впервые, сервис начал работать…

2 месяца ago