Как стать автором
Обновить
75.02
Nixys
DevOps, DevSecOps, MLOps — системный IT-интегратор

Про Ansible для новичков: Практика (часть II)

Время на прочтение15 мин
Количество просмотров10K

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

В этом материале мы будем практиковаться писать Ansible role для автоматического поднятия web-сервера.

Итак, как я уже упоминал в первой части, любое написание ansible-роли сопровождается планом. В этот план нужно включить все, что будет необходимо установить и настроить.

Если рассматривать все пункты в одной статье, то материал получается слишком объемным, - собственно, поэтому и было принято решение разделить его на две части. Вот наш план, в котором зачеркнуты первые три пункта, которые мы выполнили в первой части:

  1. Пункт 1. Первоначальная настройка сервера.

  2. Пункт 2. Установка LEMP.

  3. Пункт 3. Права и пользователь.

  4. Пункт 4. Настройка LEMP.

  5. Пункт 5. Перенос кода площадки и БД.

  6. Пункт 6. Тестирование.

  7. Пункт 7. Итог.

В этой статье выполним оставшиеся четыре этапа. Итак, на данный момент в директории /var/ansible находится:

.

├── hosts.txt

├── LEMP

│   ├── defaults

│   │   └── main.yml

│   ├── files

│   ├── handlers

│   │   └── main.yml

│   ├── meta

│   │   └── main.yml

│   ├── README.md

│   ├── tasks

│   │   ├── apache2_install.yml

│   │   ├── default_settings.yml

│   │   ├── default_user_settings.yml

│   │   ├── exim4_install.yml

│   │   ├── main.yml

│   │   ├── mysql_install.yml

│   │   └── nginx_install.yml

│   ├── templates

│   ├── tests

│   │   ├── inventory

│   │   └── test.yml

│   └── vars

│       └── main.yml

└── playbook.yml

Пункт 4. Первоначальная настройка сервера.

На этом этапе мы произведем настройку следующих сервисов:

  1. php

  2. nginx

  3. mysql

  4. apache2

  5. exim4

Настройка php.

Первым делом необходимо установить php на удаленный сервер. Для этого создаем пустой файл в /var/ansible/LEMP/tasks с названием php.yml. Используем модуль apt.

cd /var/ansible/LEMP/tasks
touch php.yml

Добавляем:

- name: install php
  apt: name={{ item }} update_cache=yes state=latest
  with_items:
  - git
  - php
  - php-curl
  - php-gd
  - php-mbstring
  - php-xml
  - php-xmlrpc
  - php-soap
  - php-intl
  - php-zip
  1. with_items: - создаем массив переменных из необходимых нам пакетов.

  2. name={{ item }} - здесь мы используем массив item для установки php модулей. apt будет выполняться до тех пор, пока не установит все пакеты из массива item.

Не забываем подключать новый yml-файл в main.yml.

В main.yml добавляем.

#####install php
  - include_tasks: php.yml

Для php нам необходимо будет передать php.ini файл.

Создаем директорию php и файл php-ansible.ini в /var/ansible/LEMP/files/.

cd /var/ansible/LEMP/files/
mkdir php
touch php/php.ini

Вставляем в файл php-ansible.ini, после [PHP], любую необходимую вам конфигурацию:

[PHP]

Далее необходимо передать этот файл в /etc/php/7.3/apache2/. Он автоматически загрузится и применится после перезагрузки интерпретатора php. В данном случае это apache2.

Открываем файл php.yml в заданиях (/var/ansible/LEMP/tasks/php.yml) и добавляем копирование файлов и перезагрузку apache2.

Добавляем:

- name: copy config
  copy:
    src: php/php-ansible.ini
    dest: /etc/php/7.3/apache2

- name: restart apache2
  service:
    name: apache2
    state: restarted

Настройка nginx.

  1. Для настройки нам необходимо перенести конфигурационные файлы nginx:

    1. nginx.conf;

    2. конфигурацию площадки. domain_name.conf.

  2. Включить площадку.

  3. Перезагрузить nginx.

Переходим в директорию /var/ansible/LEMP/files.

Создаем директорию nginx.

mkdir nginx
cd nginx/

В директории nginx необходимо создать 2 файла: nginx.conf и domain_name.conf.

touch nginx.conf domain_name.conf
  1. nginx.conf необходимо передать в корневую директорию nginx

  2. domain_name.conf необходимо передать в sites-available.

В nginx.conf вставляем конфигурацию из нашей предыдущей статьи.

В domain_name.conf конфигурацию из нашей предыдущей статьи.

После добавления конфигурации переходим в ./tasks/nginx_install.yml.

Передаем конфигурацию на удаленный сервер с помощью модуля copy и file.

Добавляем:

  - name: Copy config.
    copy:
      src: nginx/nginx.conf
      dest: /etc/nginx/nginx.conf

  - name: Copy domain_name  config
    copy:
      src: nginx/domain_name.conf
      dest: /etc/nginx/sites-available/domain_name.conf

  - name: enable site domain_name
    file:
      src: /etc/nginx/sites-available/domain_name.conf
      dest: /etc/nginx/sites-enabled/domain_name.conf
      state: link

  - name: restart nginx
    service:
      name: nginx
      state: restarted
  1. src - файл в директории ./files;

  2. dest - адрес сохранения файла на удаленном сервере.

Запускаем и проверяем:

TASK [LEMP : include_tasks] *************************************************************************************************************************************************************************************
included: /var/ansible/LEMP/tasks/nginx_install.yml for ansible2
TASK [LEMP : Install nginx] *************************************************************************************************************************************************************************************
ok: [ansible2]
TASK [LEMP : Copy config.] **************************************************************************************************************************************************************************************
changed: [ansible2]
TASK [LEMP : Copy domain_name  config] **************************************************************************************************************************************************************************
changed: [ansible2]
TASK [LEMP : enable site domain_name] ***************************************************************************************************************************************************************************
changed: [ansible2]
PLAY RECAP ******************************************************************************************************************************************************************************************************
ansible2                   : ok=4    changed=3    unreachable=0    failed=0

Конфигурация для nginx добавлена. 

Итог:

  1. Передается конфигурация nginx и domain_name.

  2. Создается символьная ссылка в sites-enabled.

  3. Перезагружается сервис.

Настройка mysql.

Необходимо создать конфигурационный файл mysql.cnf, после чего передать его на удаленный сервер.

Создаем директорию mysql в /var/ansible/LEMP/files.

cd /var/ansible/LEMP/files
mkdir mysql
cd mysql/
touch mysql.cnf

Вставляем после [mysqld] необходимую вам конфигурацию.

[mysqld]

Открываем файл конфигурации ansible mysql /var/ansible/LEMP/tasks/mysql_install.yml

Передаем файл конфигурации на удаленный сервер и перезагружаем mysql.

Добавляем:

  - name: Copy config
    copy:
      src: mysql/mysql.cnf
      dest: /etc/mysql/mysql.conf.d/mysql.cnf

  - name: restart mysql
    service:
      name: mysql
      state: restarted

Итог:

  1. Перезагружаем сервис mysql.

  2. Настройка mysql завершена.

Настройка apache2.

Делаем аналогичные действия как и у nginx

Необходимо передать

  1. apache2.conf

  2. domain_name.conf

  3. ports.conf

Создаем директорию и выше перечисленные файлы в директории /var/ansible/LEMP/files.

Конфигурации для apache2 и domain_name можно взять из следующих статей:

  1. Конфигурация apache2.conf

  2. Конфигурация domain_name.conf.

Настраиваем работу apache2 на 81 порту. Добавляем конфигурацию для ports.conf:

Listen 81
<IfModule ssl_module>
         Listen 443
</IfModule>

<IfModule mod_gnutls.c>
         Listen 443
</IfModule>

Далее идем в /var/ansible/LEMP/tasks/apache2_install.yml

Добавляем:

 - name: copy config
    copy:
      src: apache2/apache2.conf
      dest: /etc/apache2/apache2.conf

  - name: copy domain_name config
    copy:
      src: apache2/domain_name.conf
      dest: /etc/apache2/sites-available/domain_name.conf

  - name: enable site domain_name
    file:
      src: /etc/apache2/sites-available/domain_name.conf
      dest: /etc/apache2/sites-enabled/domain_name.conf
      state: link

  - name: copy ports
    copy:
      src: apache2/ports.conf
      dest: /etc/apache2/ports.conf

  - name: restart apache2
    service:
      name: apache2
      state: restarted

Итог:

  1. Передаются файлы конфигурации;

  2. Перезагружаем сервис apache2.

Настройка exim4.

Необходимо:

  1. Передать файл конфигурации /etc/exim4/update-exim4.conf.conf;

  2. Перезагрузить exim4.

Создаем директорию exim4 и файл update-exim4.conf.conf в /var/ansible/LEMP/files.

Добавляем в файл конфигурации exim4:

# /etc/exim4/update-exim4.conf.conf
#
# Edit this file and /etc/mailname by hand and execute update-exim4.conf
# yourself or use 'dpkg-reconfigure exim4-config'
#
# Please note that this is _not_ a dpkg-conffile and that automatic changes
# to this file might happen. The code handling this will honor your local
# changes, so this is usually fine, but will break local schemes that mess
# around with multiple versions of the file.
#
# update-exim4.conf uses this file to determine variable values to generate
# exim configuration macros for the configuration file.
#
# Most settings found in here do have corresponding questions in the
# Debconf configuration, but not all of them.
#
# This is a Debian specific file
dc_eximconfig_configtype='local'
dc_other_hostnames='domain_name'
dc_local_interfaces='127.0.0.1 ; ::1'
dc_readhost=''
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost=''
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname=''
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'

В данный файл добавляете нужную вам конфигурацию.

В файл конфигурации (/var/ansible/LEMP/tasks/exim4_install.yml) добавляем "копирование файла" и "перезагрузка exim4".

  - name: copy config
    copy:
      src: exim4/update-exim4.conf.conf
      dest: /etc/exim4/update-exim4.conf.conf

  - name: restart exim4
    service:
      name: exim4
      state: restarted

Конфигурация для exim4 готова.

Структура директории files с конфигурацией:

├── files

│   ├── apache2

│   │   ├── apache2.conf

│   │   ├── domain_name.conf

│   │   └── ports.conf

│   ├── exim4

│   │   └── update-exim4.conf.conf

│   ├── mysql

│   │   └── mysql.cnf

│   ├── nginx

│   │   ├── domain_name.conf

│   │   └── nginx.conf

│   └── php

│       └── php-ansible.ini

На данный момент настройка сервисов завершена. Если необходимо прокидывать или менять дополнительные файлы, вы также их можете добавить и изменить по выше указанному методу.

Пункт 5. Перенос кода площадки и БД.

В данном пункте необходимо переместить dump площадки для загрузки в БД и перенести код площадки.

Нам понадобится 2 директории в директории files.

Это:

  1. mysql_dump - директория с дампом площадки;

  2. data - директория с кодом.

Для начала добавляем код площадки в директорию /data.

В нашем случае кодом площадки будет выступать установщик wordpress.

Далее переносим дамп вашей БД в директорию /mysql_dump.

Создаем новый yml-файл с названием file.yml по адресу /var/ansible/LEMP/tasks/.

Включаем его в main.yml

  ####add_site_file
  - include_tasks: file.yml

Добавляем в него задание:

  - name: copy file domain_name
    copy:
      src: data/
      dest: /var/www/domain_name/data/
      owner: domain_name
      group: domain_name

  - name: copy dump
    copy:
      src: mysql_dump/dump.sql
      dest: /tmp/dump.sql

  - name: mysql_dump
    mysql_db:
      name: domain_name_db
      state: import
      target: /tmp/dump.sql
      login_user: root
      login_password: "{{ mysql_root_password }}"

Для того, чтоб загрузить дамп в БД, используется модуль mysql_db.

Файлы площадки и дамп переместили на сервер.

Пункт 6. Тестирование.

На данный момент структура директорий выглядит следующим образом:
.
├── hosts.txt
├── LEMP
│   ├── defaults
│   │   └── main.yml
│   ├── files
│   │   ├── apache2
│   │   │   ├── apache2.conf
│   │   │   ├── domain_name.conf
│   │   │   └── ports.conf
│   │   ├── data
│   │   ├── exim4
│   │   │   └── update-exim4.conf.conf
│   │   ├── mysql
│   │   │   └── mysql.cnf
│   │   ├── mysql_dump
│   │   │   └── dump.sql
│   │   ├── nginx
│   │   │   ├── domain_name.conf
│   │   │   └── nginx.conf
│   │   └── php
│   │       └── php-ansible.ini
│   ├── handlers
│   │   └── main.yml
│   ├── meta
│   │   └── main.yml
│   ├── README.md
│   ├── tasks
│   │   ├── apache2_install.yml
│   │   ├── default_settings.yml
│   │   ├── default_user_settings.yml
│   │   ├── exim4_install.yml
│   │   ├── file.yml
│   │   ├── main.yml
│   │   ├── mysql_install.yml
│   │   ├── nginx_install.yml
│   │   └── php.yml
│   ├── templates
│   ├── tests
│   │   ├── inventory
│   │   └── test.yml
│   └── vars
│       └── main.yml
├── php.ini
├── playbook.retry
└── playbook.yml

Конфигурация заданий в директории .tasks:

apache2_install.yml:

  - name: Install apache2
    apt:
      name: apache2
      state: latest

  - name: copy config
    copy:
      src: apache2/apache2.conf
      dest: /etc/apache2/apache2.conf

  - name: copy domain_name config
    copy:
      src: apache2/domain_name.conf
      dest: /etc/apache2/sites-available/domain_name.conf

  - name: copy ports
    copy:
      src: apache2/ports.conf
      dest: /etc/apache2/ports.conf

  - name: restart apache2
    service:
      name: apache2
      state: restarted

default_settings.yml:

  - name: update repo.
    shell: apt update

  - name: install default app.
    shell:
      cmd: "apt install -y dirmngr mc iotop htop telnet tcpdump nmap curl hexedit sudo zip unzip patch pwgen vim less parted subversion ntp bzip2 lsof strace mutt s-nail ncdu smartmontools tree dnsutils logrotate rsyslog"

  - name: time
    shell:
      cmd: "timedatectl set-timezone {{time_zone}}"

  - name: locale settings
    shell:
      cmd: 'locale-gen {{locale1}} && update-locale LANG={{locale2}} LC_TIME="{{locale1}}"'

  - name: hostname
    shell:
      cmd: "hostnamectl set-hostname {{DOMAIN_NAME}}"

default_user_settings.yml:

  - name: add group
    group:
      name: "{{ DOMAIN_NAME }}"
      state: present
      gid: "{{ Group_GID }}"

  - name: add user
    user:
      name: "{{ DOMAIN_NAME }}"
      password: "{{ user_password | password_hash('sha512') }}"
      uid: "{{ User_uid }}"
      group: "{{ DOMAIN_NAME }}"
      state: present
      update_password: on_create
      home: "/var/www/{{ DOMAIN_NAME }}"
      shell: /bin/bash

  - name: create home directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0751
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/data"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/log"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/sess"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/tmp"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/upload"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/log/apache2"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

  - name: create other directory
    file:
      path: "/var/www/{{ DOMAIN_NAME }}/log/nginx"
      owner: "{{ DOMAIN_NAME }}"
      group: "{{ DOMAIN_NAME }}"
      mode: 0755
      state: directory

exim4_install.yml:

  - name: Install exim4
    apt:
      name: exim4
      state: latest

  - name: copy config
    copy:
      src: exim4/update-exim4.conf.conf
      dest: /etc/exim4/update-exim4.conf.conf

  - name: restart exim4
    service:
      name: exim4
      state: restarted

main.yml:

#  - include_tasks: default_settings.yml
  #####install mysql
#  - include_tasks: mysql_install.yml
  #####install nginx
#  - include_tasks: nginx_install.yml
  #####install apache2
#  - include_tasks: apache2_install.yml
  #####install exim4
#  - include_tasks: exim4_install.yml
  #####default user settings
#  - include_tasks: default_user_settings.yml
  #####install php
#  - include_tasks: php.yml
  #####copy file domain_name
  - include_tasks: file.yml

mysql_install.yml:

  - name: add mysql repo
    get_url:
      url: https://dev.mysql.com/get/mysql-apt-config_0.8.6-1_all.deb
      dest: "/tmp"
      mode: 0440

  - name: install mysql repo
    apt: "deb=/tmp/mysql-apt-config_0.8.6-1_all.deb"
    become: true

  - name: add key mysql and update repo
    shell: "apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29 && apt update"

  - name: install python-mysqldb
    apt:
      name: python-mysqldb
      state: present
      update_cache: yes

  - name: check latest version of mysql 5.7
    command: bash -c "apt-cache showpkg mysql-server|grep 5.7|head -1|cut -d' ' -f1"
    register: latestmysql57
  - debug: msg="{{ latestmysql57.stdout }}"

  - name: install mysql 57
    apt:
      name: mysql-server={{ latestmysql57.stdout }}
      state: present
      update_cache: yes

  - name: update mysql root password for all root accounts
    become: true
    mysql_user:
      name: root
      host: "{{ item }}"
      password: "{{ mysql_root_password }}"
      login_user: root
      login_password: 12345
      check_implicit_admin: yes
      priv: "*.*:ALL,GRANT"
      state: present
    with_items:
      - 127.0.0.1
      - ::1
      - localhost

  - name: Create a new database with name 'DOMAIN_NAME_DB'
    mysql_db:
      login_user: root
      login_password: "{{ mysql_root_password }}"
      name: "{{name_db}}"
      state: present

  - name: add user DOMAIN_NAME_USR
    mysql_user:
      login_user: root
      login_password: "{{ mysql_root_password }}"
      host: localhost
      name: "{{user_db}}"
      password: "{{password_user_db}}"
      priv: '{{name_db}}.*:ALL,GRANT'
      state: present

  - name: Copy config
    copy:
      src: mysql/mysql.cnf
      dest: /etc/mysql/mysql.conf.d/mysql.cnf

  - name: restart mysql
    service:
      name: mysql
      state: restarted

nginx_install.yml:

  - name: Install nginx
    apt:
      name: nginx
      state: latest

  - name: Copy config.
    copy:
      src: nginx/nginx.conf
      dest: /etc/nginx/nginx.conf

  - name: Copy domain_name  config
    copy:
      src: nginx/domain_name.conf
      dest: /etc/nginx/sites-available/domain_name.conf

  - name: enable site domain_name
    file:
      src: /etc/nginx/sites-available/domain_name.conf
      dest: /etc/nginx/sites-enabled/domain_name.conf
      state: link

  - name: restart nginx
    service:
      name: nginx
      state: restarted

php.yml:

- name: install php
  apt: name={{ item }} update_cache=yes state=latest
  with_items:
  - git
  - php
  - php-curl
  - php-gd
  - php-mbstring
  - php-xml
  - php-xmlrpc
  - php-soap
  - php-intl
  - php-zip

- name: copy config
  copy:
    src: php/php-ansible.ini
    dest: /etc/php/7.3/apache2

- name: restart apache2
  service:
    name: apache2
    state: restarted

Файл с переменными /var/ansible/LEMP/vars/main.yml:

DOMAIN_NAME: domain_name
locale1: ru_RU.UTF-8
locale2: en_US.UTF-8
time_zone: Europe/Moscow
User_uid: 10000
Group_GID: 10000
user_password: password
mysql_root_password: password
name_db: domain_name_db
user_db: domain_name_usr
password_user_db: password

Для тестирование переходим на удаленный сервер. Добавляем в /etc/hosts запись вида:

127.0.0.1 domain_name.com

Проверяем статусы сервисов:

systemctl status nginx apache2 mysql exim4

Если все сервисы работают, делаем запрос на сайт с помощью curl.

# curl -LI domain_name.com
HTTP/1.1 302 Found
Server: nginx
Date: Wed, 29 Jun 2022 11:32:10 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Keep-Alive: timeout=15
Location: http://domain_name.com/wp-admin/setup-config.php

HTTP/1.1 200
Server: nginx
Date: Wed, 29 Jun 2022 11:32:10 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Keep-Alive: timeout=15
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0

Все работает! Далее необходимо настраивать площадку в веб интерфейсе.

Пункт 7. Итог.

Ну вот мы с вами и познакомились с Ansible и базовыми модулями, которые чаше всего используется в его работе. Разумеется, данная роль ansible не является идеальной, и создана лишь для обучения. Этого мини-курса вполне будет достаточно, чтобы понять, как работает ansible на базовом уровне.

Если у вас остались вопросы, можете задавать их в комментариях. Ставьте лайки и подписывайтесь на нас - в дальнейшем будем публиковать еще больше обучающих статьей.

Также подписывайтесь на наш telegram-канал DevOps FM.

Рекомендации для чтения:

Зашита от dos/ddos.

Обучение docker.

10 частых ошибок в настройке nginx.

Настройка LEMP сервера с нуля.

Теги:
Хабы:
Всего голосов 11: ↑9 и ↓2+7
Комментарии16

Публикации

Информация

Сайт
nixys.ru
Дата регистрации
Дата основания
Численность
51–100 человек
Местоположение
Россия
Представитель
Vlada Grishkina-Makareva