Разворачиваем LAMP-стек в Ubuntu Trusty, Debian 11 и Centos 7 с использованием Ansible

Итак, в предыдущих записях по теме LAMP я не рассмотрел сам процесс настройки серверов. Восполним этот пробел. Будет много букв.

Настраивать LAMP на сервере будем при помощи Ansible. Для этого у меня подготовлен файл lamp.yml, который буде приведён ниже. Могу что-то упустить, но в принципе предыдущие статьи должны восполнить пробелы.

Итак, поехали.

Для облегчения себе жизни и нехранения паролей в открытом виде, восспользуемся входом на удалённые сервера по ключу. Для генерации пары ключей (открытый-закрытый), выполним команду:

ssh-keygen -t rsa -b 4069 # на запрос имени файла ключа, вводим имя ansible.key

После выполнения этой команды, создадутся 2 файла: открытый ключ ansible.key.pub и закрытый ключ ansible.key.

Теперь наш открытый (также его еще называют публичный — public) ключ необходимо доставить на управляемый сервер:

ssh-copy-id -i ansible.key.pub -o StrictHostKeyChecking=no admin@192.168.88.23

Ключ StrictHostKeyChecking=no скажет нашему клиенту не ругаться на незнакомые сервера. На запрос пароля пользователя admin, вводим его.

Кроме того, на нашей админской машине необходимо убедиться, что агент SSH запущен и дабавить наш закрытый ключ в его хранилище:

eval "$(ssh-agent -s)"
ssh-add ansible.key

Далее пробуем подсоединиться к серверу, никаких дополнительных запросов быть не должно:

ssh admin@192.168.88.23

Если мы увидели командную строку удалённого сервера, то значить всё сделали правильно и можно двигаться дальше.

Теперь проверим, что Ansible также сможет работать с удаленной машиной, выполнив простую команду для просмотра её конфигурации:

ansible web-trusty -m setup >> trusty.txt

Чтобы после каждой перезагрузки нашей управляющей машины не добавлять ключ в хранилище агента заново, создадим вложенную папку ./key/ в папке с файлом lamp.yml и положим туда ключ ansible.key. Запомним это действие.

В файле inventory (также будет приведён ниже) создана группа prod_WEB в которую включён наш будущий lamp-сервер с ip-адресом 192.168.88.23 с присвоенным именем web-trusty. Также, в плэйбуке используется ряд переменных (например, путь до закрытого ключа в папке key), которые вынесены в отдельный файл prod_WEB (должен совпадать с именем группы в inventory), находящийся во вложенной папке ./group_vars/. Имейте в виду, что, в данном конкретном случае, это имя видно только для Ansible.

Файл inventory:

[prod_WEB]
web-trusty ansible_host=192.168.88.21

Файл с переменными ./group_vars/prod_WEB:

---
ansible_user: admin
ansible_ssh_private_key_file: ./keys/ansible.key
app_user: "admin"
http_host: "{{ ansible_fqdn }}"
http_conf: "home.local.conf"
http_port: "80"
disable_default: true

Обратите внимание, что файл должен начинатья с трёх тире!!

Дабы передать в плэйбук при запуске значение переменной HOSTS, воспользуемся ключём —extra-vars, который позволяет заменить переменную, объявленную в тексте плэйбука, атакже переопределить вообще любую переменную нашего проекта. Имейте это в виду и пользуйтесь.

Итак, файл lamp.yml:

---
- name: LAMP servers install & configure
  hosts: "{{ HOSTS | default('test_WEB') }}"
  become: yes
# ниже закоментаренные переменные, которые мы перенесли в папку ./group_vars
#  vars:
#    app_user: "admin"
#    http_host: "{{ ansible_fqdn }}"
#    http_conf: "home.local.conf"
#    http_port: "80"
#    disable_default: true

  tasks: 
  - name: Install LAMP stack for Ubuntu Trusty
    block:
    - name: Install LAMP Packages Ubuntu Trusty
      apt: name={{ item }} update_cache=yes state=latest
      loop: [ 'apache2', 'mysql-server', 'python-mysqldb', 'php5', 'php5-mysql', 'libapache2-mod-php5' ]
    - name: Ensure Apache is running
      service: name=apache2 state=started enabled=yes
    - name: UFW - Allow HTTP on port {{ http_port }} (for trusty)
      ufw:
        rule: allow
        port: "{{ http_port }}"
        proto: tcp
    when: ansible_distribution_release == "trusty"

  - name: Install LAMP stack for Debian Bullseye
    block:
    - name: Install LAMP Packages Debian Bullseye
      apt: name={{ item }} update_cache=yes state=latest
      loop: [ 'apache2', 'default-mysql-server', 'python3-pymysql', 'php', 'php-mysql', 'libapache2-mod-php', 'php-mbstring', 'php-gd', 'php-dom' ]
    - name: Ensure Apache is running
      service: name=apache2 state=started enabled=yes
    when: ansible_distribution_release == "bullseye"

  - name: Install LAMP stack for RedHat
    block:
    - name: Install Apache (for RedHat)
      yum: name={{ item }} state=latest
      loop:
        - httpd
        - mariadb
        - mariadb-server
        - MySQL-python
        - php
        - php-pear
        - php-gd
        - php-xml
        - php-mysqlnd
        - php-mbstring
    - name: Ensure Apache, MySQL and PHP is running (for RedHat)
      service: name={{ item }} state=started enabled=yes
      loop: 
        - httpd
        - mariadb
    - name: Ensure firewalld started & anabled on boot (for RedHat)
      service: name=firewalld enabled=yes state=started
    - name: Open port {{ http_port }} for tcp (for RedHat)
      firewalld: port={{ http_port }}/tcp permanent=yes state=enabled 
      notify: Restart firewalld    
    when: ansible_os_family == "RedHat"

  - name: Create document root
    file:
      path: "/var/www/{{ http_host }}"
      state: directory
      owner: "{{ app_user }}"
      mode: '0755'

  - name: Sets Up PHP Info Page
    template:
      src: "files/info.php"
      dest: "/var/www/{{ http_host }}/info.php"

  - name: Enable new site for Ubuntu/Debian
    block:
    - name: Set up Apache virtualhost (for Ubuntu/Debian)
      template:
        src: "files/apache2.conf.j2"
        dest: "/etc/apache2/sites-available/{{ http_conf }}"
    - name: Enable site (for Ubuntu/Debian)
      shell: /usr/sbin/a2ensite {{ http_conf }}
    - name: Disable default Apache site (for Ubuntu/Debian)
      shell: /usr/sbin/a2dissite 000-default.conf
      when: disable_default
      notify: Restart Apache Debian
    when: ansible_os_family == "Debian"

  - name: Enable new site for RedHat
    block:
      - name: Turn on CONF.D folder scan
        shell: sed -i 's/#IncludeOptional conf.d/IncludeOptional conf.d/g' /etc/httpd/conf/httpd.conf
      - name: Set up Apache virtualhost for RedHat
        template:
          src: "files/apache2.conf.j2"
          dest: "/etc/httpd/conf.d/{{ http_conf }}"
        notify: Restart Apache RedHat
    when: ansible_os_family == "RedHat"

  handlers:
  - name: Restart firewalld
    service: name=firewalld state=restarted

  - name: Restart Apache RedHat
    service: name=httpd state=restarted
    
  - name: Restart Apache Debian
    service: name=apache2 state=restarted

Настройку MySQL я выполнял при помощи другого плэйбука (приводил его в отдельной записи здесь), по идее это всё надо делать с помощью ролей, но как сделал — так сделал. Содержимое mysql.yml ниже:

---
- name: Test playbook for initial installed MySQL
  hosts: "{{ HOSTS | default('test_WEB') }}"
  become: yes
  vars:
    mysql_root_password: "superpassword"
    mysql_dbuser_password: "puperpassword"

  tasks:
  # MySQL Configuration

  - name: Sets the root password (Centos 7)
    mysql_user: name=root host={{ item }} password={{ mysql_root_password }}
    with_items:
    - "{{ ansible_hostname }}"
    - 127.0.0.1
    - ::1
    - localhost
    when: ansible_os_family == "RedHat"

  - name: Sets the root password (Debian/Ubuntu)
    mysql_user: name=root host={{ item }} password={{ mysql_root_password }} login_unix_socket="/var/run/mysqld/mysqld.sock"
    with_items:
    - "{{ ansible_hostname }}"
    - 127.0.0.1
    - ::1
    - localhost
    when: ansible_os_family == "Debian"

  - name: Copy .my.cnf file with root password credentials
    template: src=files/my.cnf.j2 dest=/root/.my.cnf owner=admin mode=0600

  - name: Removes all anonymous user accounts
    mysql_user:
      name: ''
      host_all: yes
      state: absent
      login_user: root
      login_password: "{{ mysql_root_password }}"

  - name: Add dbuser for WordPress to MySQL config
    mysql_user:
      name: dbuser
      password: "{{ mysql_dbuser_password }}"
      host: localhost
      priv: 'webdb.*:ALL,GRANT'
      state: present
      login_user: root
      login_password: "{{ mysql_root_password }}"

Приведенные плэйбуки успешно отработали на Debian 11 Bullseye, Ubuntu Trusty и Centos 7, если что…

Содержимое вспомогательных файлов в папке files проекта приведу ниже.

info.php:

<?php
phpinfo();
?>

Шаблон конфигурации Apache apache2.conf.j2:

<VirtualHost *:{{ http_port }}>
   ServerAdmin webmaster@localhost
   ServerName {{ http_host }}
   ServerAlias www.{{ http_host }}
   DocumentRoot /var/www/{{ http_host }}

   <Directory /var/www/{{ http_host }}>
         Options -Indexes
   </Directory>

   <IfModule mod_dir.c>
       DirectoryIndex index.php index.html index.cgi index.pl  index.xhtml index.htm
   </IfModule>

</VirtualHost>

Шаблон конфигурации клиента MySQL my.cnf.j2:

[client]
user=root
password={{ mysql_root_password }}

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

ansible-playbook lamp.yml --extra-var HOSTS=prod_WEB
ansible-playbook mysql.yml --extra-var HOSTS=prod_WEB

В приведенной команде, плэйбуки lamp.yml и mysql.yml применяются ко всей группе prod_WEB. Также, мы могли передать в переменную HOSTS и имя web-trusty. Результат был бы тем же.

PROFIT!!!!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *