[Перевод] Автоматизация установки и удаления LAMP-стека с помощью Ansible
В этом руководстве мы рассмотрим, как автоматизировать установку и удаление LAMP-стека (Linux, Apache, MySQL, PHP) с помощью Ansible. Ansible — это инструмент автоматизации с открытым исходным кодом, который позволяет вам определять инфраструктуру и управлять ею как кодом.
Введение
Стек LAMP — это популярный пакет программного обеспечения, используемый для развертывания веб-приложений. Он состоит из следующих компонентов:
Linux: операционная система (в данном случае мы используем инстанс Amazon Linux).
Apache: веб-сервер, отвечающий за обслуживание веб-контента.
MySQL/MariaDB: система управления реляционными базами данных для хранения данных приложений.
PHP: серверный язык сценариев для динамического веб-контента.
Мы будем использовать Ansible для автоматизации установки и настройки этих компонентов.
Что понадобится
Прежде чем мы начнем, убедитесь, что у вас есть:
Создание Ansible Playbook
Начнем с создания плейбука Ansible, который установит стек LAMP и настроит компоненты.
---
- name: "Installing LAMP stack and configuring"
hosts: amazon
become: true
vars_files:
- httpd.vars
- mariadb.vars
- packages.vars
tasks:
# Task 1: Installing Packages
- name: "Installing Packages"
yum:
name: "{{ packages }}"
state: present
tags:
- lamp
- never
# Task 2: Enabling/Restarting services
- name: "Enabling/Restarting services"
service:
name: "{{ item }}"
state: restarted
enabled: true
with_items: "{{ services }}"
tags:
- lamp
- never
# Task 3: Creating httpd.conf from template
- name: "Creating httpd.conf from httpd.conf.tmpl"
template:
src: httpd.conf.tmpl
dest: /etc/httpd/conf/httpd.conf
tags:
- lamp
- never
# Task 4: Creating Virtual host
- name: "Creating Virtual host"
template:
src: virtualhost.conf.tmpl
dest: /etc/httpd/conf.d/default.conf
owner: "{{ httpd_owner }}"
group: "{{ httpd_group }}"
tags:
- lamp
- never
# Task 5: Creating docroot for the website
- name: "Creating docroot for {{ hostname }}"
file:
path: "/var/www/html/default/"
state: directory
owner: "{{ httpd_owner }}"
group: "{{ httpd_group }}"
tags:
- lamp
- never
# Task 6: Setting python3 mysql module PyMySQL
- name: "Setting python3 mysql module PyMySQL"
pip:
name: PyMySQL
tags:
- lamp
- mariadb
- never
# Task 7: Setting ROOT password for mariadb-server
- name: "Setting ROOT password for mariadb-server"
ignore_errors: true
mysql_user:
login_user: "root"
login_password: ""
login_unix_socket: /var/lib/mysql/mysql.sock
name: "root"
password: "{{ mariadb_root_password }}"
tags:
- lamp
- mariadb
- never
# Task 8: Creating DB for the website
- name: "Creating DB for blog - {{blog_db_name}}"
mysql_db:
login_user: "root"
login_password: "{{ mariadb_root_password }}"
login_unix_socket: /var/lib/mysql/mysql.sock
name: "{{ blog_db_name }}"
state: present
tags:
- lamp
- mariadb
- never
# Task 9: Creating extra user for WordPress
- name: "Creating extra user for WordPress - {{extra_user_name}}"
mysql_user:
login_user: "root"
login_password: "{{ mariadb_root_password }}"
login_unix_socket: /var/lib/mysql/mysql.sock
name: "{{ extra_user_name }}"
password: "{{ extra_user_password }}"
host: "%"
priv: "{{ blog_db_name }}.*:ALL"
tags:
- lamp
- never
- mariadb
# Task 10: Downloading WordPress
- name: "Downloading WordPress using URL"
get_url:
url: "{{ wp_url }}"
dest: "/tmp/wordpress.tar.gz"
tags:
- lamp
- mariadb
- wordpress
- never
# Task 11: Extracting WordPress
- name: "Extracting WordPress"
unarchive:
src: "/tmp/wordpress.tar.gz"
dest: "/tmp/"
remote_src: true
tags:
- lamp
- mariadb
- wordpress
- never
# Task 12: Copying WordPress files to docroot
- name: "Copying WordPress files to docroot"
copy:
src: "/tmp/wordpress/"
dest: "/var/www/html/default/"
remote_src: true
owner: "{{ httpd_owner }}"
group: "{{ httpd_group }}"
tags:
- lamp
- mariadb
- wordpress
- never
# Task 13: Copying wp-config.php file to remote server
- name: "Copying wp-config.php file to remote server"
template:
src: "./wp-config.php.tmpl"
dest: "/var/www/html/default/wp-config.php"
owner: "{{ httpd_owner }}"
group: "{{ httpd_group }}"
tags:
- lamp
- mariadb
- wordpress
- never
# Task 14: Post Installation Cleanup
- name: "Post Installation Cleanup"
file:
path: "{{ item }}"
state: absent
with_items:
- "/tmp/wordpress/"
- "/tmp/wordpress.tar.gz"
tags:
- wordpress
# Task 15: Removing Packages
- name: "Removing Packages"
yum:
name: "{{ packages }}"
state: absent
tags:
- cleanup
- never
# Task 16: Removing Directories
- name: "Removing Directories"
file:
path: "{{ item }}"
state: absent
with_items:
- /etc/httpd/conf/httpd.conf
- /etc/httpd/conf.d/default.conf
- /var/www/html/default/
tags:
- cleanup
- never
Плейбук состоит из нескольких задач, каждая из которых отвечает за определенное действие.
Задача 1: Установка пакетов: устанавливает необходимые пакеты для стека LAMP.
Задача 2. Включение/перезапуск служб. Обеспечивает включение и перезапуск необходимых служб.
Задача 3: Создание httpd.conf из шаблона: Генерирует файл конфигурации HTTP-сервера Apache из шаблона.
Задача 4. Создание виртуального хоста. Создает файл конфигурации виртуального хоста для веб-сайта по умолчанию.
Задача 5: Создание docroot для веб-сайта: Создает корневой каталог документов для веб-сайта.
Задача 6: Настройка модуля python3 mysql PyMySQL: Устанавливает модуль PyMySQL для Python.
Задача 7: Установка пароля ROOT для mariadb-server: Установка пароля root для сервера MariaDB.
Задача 8: Создание БД для сайта.
Задача 9: Создание дополнительного пользователя с привилегиями для базы данных WordPress.
Задача 10: Загрузка WordPress: получение исходного кода WordPress по указанному URL-адресу.
Задача 11: Извлечение архива WordPress.
Задача 12: Копирование файлов WordPress в корневой каталог документа.
Задача 13: Копирование файла wp-config.php на удаленный сервер: Создает файл wp-config.php для WordPress.
Задача 14: Очистка после установки: очищает временные файлы и каталоги.
Задача 15. Удаление пакетов, которые были установлены в процессе.
Задача 16: Удаление каталогов, которые были созданы в процессе.
Теги
Теги в Ansible позволяют выборочно запускать определенные задачи или группы задач в плейбуке. Вы можете назначать теги задачам с помощью tags
атрибута, а затем указывать нужные теги при запуске плейбука.
Для запуска определенных задач с использованием тегов вы можете использовать опцию --tags
с командойansible-playbook
. Вот пример команды:
ansible-playbook lamp.yml --tags lamp
В приведенной выше команде будут выполняться только задачи, отмеченные lamp
.
Вы также можете исключить определенные задачи, используя --skip-tags
опцию. Например, чтобы пропустить задачи с тегом never
, вы можете использовать следующую команду:
ansible-playbook lamp.yml --skip-tags never
В этом случае задачи с тегом never
не будут выполняться.
Кроме того, вы можете перечислить все доступные теги в playbook, используя опцию --list-tags
. Вот пример команды:
ansible-playbook lamp.yml --list-tags
Эта команда отобразит список всех тегов, определенных в вашем плейбуке.
Используя теги, вы можете настроить выполнение вашего плейбука в соответствии с конкретными требованиями, что обеспечивает большую гибкость и контроль.
Шифрование
Чтобы зашифровать lamp.yml
плейбук с помощью Ansible Vault, вы можете использовать команду ansible-vault
. Ansible Vault предоставляет безопасный способ шифрования конфиденциальных данных в ваших книгах.
Вот команда для шифрования lamp.yml
файла:
ansible-vault encrypt lamp.yml
После выполнения этой команды вам будет предложено ввести и подтвердить пароль для защиты зашифрованного файла. Обязательно запомните этот пароль, так как он понадобится вам позже для расшифровки файла.
Как только lamp.yml
файл будет зашифрован, его содержимое будет зашифровано и станет нечитаемым без предварительной расшифровки.
Чтобы запустить playbook с зашифрованным файлом, вы можете использовать команду ansible-playbook
вместе с --ask-vault-pass
опцией ввода пароля:
ansible-playbook lamp.yml --ask-vault-pass
При появлении запроса введите пароль, который вы использовали для шифрования файла.
Обратите внимание, что вы также можете указать пароль через файл или ссылку на файл паролей, используя параметр --vault-password-file
, который может быть полезен при автоматизации выполнения зашифрованных книг воспроизведения.
Зашифровав playbook с помощью Ansible Vault, вы можете защитить конфиденциальную информацию, такую как пароли, ключи API или любые другие конфиденциальные данные, которые могут присутствовать в вашем playbook.
Для дополнительной безопасности я предпринял следующие шаги:
Во-первых, я создал запись Secrets Manager в AWS для безопасного хранения пароля моего хранилища. Это гарантирует, что конфиденциальная информация хранится в зашифрованном виде и недоступна для неавторизованных пользователей.
Затем я создал политику IAM, которая предоставляет доступ на чтение к диспетчеру секретов.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SecretsManagerReadAccess",
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:ap-south-1:939486479455:secret:vault_pass-yAAbi4"
}
]
}
После создания политики я создал роль IAM, которая использует эту политику. Эта роль будет прикреплена к моей главной машине, что позволит ей безопасно получить пароль хранилища от Secrets Manager.
Чтобы получить пароль хранилища из Secrets Manager, я создал сценарий bash. Сценарий использует AWS CLI команду aws secretsmanager get-secret-value
и передает секретный идентификатор в качестве аргумента (vault_pass
). Затем сценарий извлекает значение пароля из ответа JSON с помощью jq
и сохраняет его в secret_value
переменной.
Вот пример bash-скрипта:
#!/bin/bash
secret_id="vault_pass"
secret_value=$(aws secretsmanager get-secret-value --secret-id "$secret_id" --query 'SecretString' --output text | jq -r '.vault_pass')
# Use the secret value in further operations
if [ -n "$secret_value" ]; then
# Perform desired operations using the secret value
echo "Retrieved the vault password: $secret_value"
else
echo "Failed to retrieve the vault password"
fi
Запустив этот сценарий, я могу безопасно получить пароль хранилища от Secrets Manager.
Наконец, чтобы использовать пароль хранилища в моем плейбуке Ansible, я передаю сценарий в качестве аргумента командной строки вместе с командой ansible-playbook
. Это гарантирует, что плейбук будет иметь доступ к паролю хранилища, когда это необходимо.
ansible-playbook -i inventory lamp.yml --vault-password-file
Заключение
С помощью этого плейбука Ansible и скрипта AWS Secrets Manager можно автоматизировать установку и настройку LAMP-стека. Это позволяет эффективно управлять инфраструктурой и упрощает процесс развертывания.
Если вы хотите научиться устанавливать LEMP-стеки, собирать Docker-контейнеры в Ansible, самостоятельно писать плейбуки, использовать роли и модули, приходите на курс «Ansible: Infrastructure as Code». Новый поток стартует 7 августа. Посмотреть программу и записаться на курс можно на нашем сайте. Ждём на курсе!