jonaspammer.apache2
// Этот файл генерируется .github/workflows/gh-pages.yml - все локальные изменения будут в конечном итоге потеряны!
= ansible-role-apache2
Йонас Паммер <[email protected]>;
:toc: слева
:toclevels: 2
:toc-placement!:
:source-highlighter: rouge
https://galaxy.ansible.com/jonaspammer/apache2[изображение:https://img.shields.io/badge/available%20on%20ansible%20galaxy-jonaspammer.apache2-brightgreen[Версия на Galaxy]]
// Очень важные статусные бейджи
https://github.com/JonasPammer/ansible-role-apache2/actions/workflows/ci.yml[изображение:https://github.com/JonasPammer/ansible-role-apache2/actions/workflows/ci.yml/badge.svg[Тестирование CI]]
Роль Ansible для установки Apache2, включения/выключения модулей, настройки его параметров по умолчанию и создания виртуальных хостов.
toc::[]
[[meta]]
== 🔎 Метаданные
Ниже вы можете найти информацию о…
* требуемой версии Ansible для этой роли
* поддерживаемых платформах
* зависимостях этой роли
.link:meta/main.yml[]
[source,yaml]
----
---
galaxy_info:
role_name: "apache2"
description:
"Роль ansible для установки Apache2, включения/выключения модулей,
настройки его параметров по умолчанию и создания виртуальных хостов.
Основана на роли apache2 от geerlingguy."
author: "jonaspammer"
license: "MIT"
min_ansible_version: "2.11"
platforms:
- name: EL # (Enterprise Linux)
versions:
- "9" # активно тестировалось: rockylinux9
- name: Fedora
versions:
- "38" # активно тестировалось: fedora38
- "39" # активно тестировалось: fedora39
- name: Debian
versions:
- bullseye # активно тестировалось: debian11
- bookworm # активно тестировалось: debian12
- name: Ubuntu
versions:
- focal # активно тестировалось: ubuntu2004
- jammy # активно тестировалось: ubuntu2204
galaxy_tags:
- web
- apache
- webserver
- html
- httpd
dependencies: []
allow_duplicates: true
----
[[requirements]]
== 📌 Требования
// Здесь должны быть указаны любые предварительные условия, которые могут не покрываться этой ролью или самим Ansible.
Пользователь Ansible должен иметь возможность `become`.
Если вы используете SSL/TLS (<<apache_vhosts_ssl>>), вам понадобятся собственные файлы сертификата и ключа.
Если вы используете Apache с PHP, я рекомендую использовать роль
https://github.com/geerlingguy/ansible-role-php/[geerlingguy.php]
для установки PHP, и вы можете использовать либо `mod_php`
(добавив правильный пакет, например `libapache2-mod-php5` для Ubuntu, в `php_packages`),
либо также использовать
https://github.com/geerlingguy/ansible-role-apache-php-fpm[`geerlingguy.apache-php-fpm`]
для подключения Apache к PHP через FPM.
Пожалуйста, ознакомьтесь с README указанных ролей для получения более конкретной информации.
При работе с системами на базе Solaris,
коллекция https://galaxy.ansible.com/community/general[`community.general`]
(содержит модуль `pkg5`) должна быть установлена на контроллере Ansible.
При работе с системами на базе Suse,
https://galaxy.ansible.com/community/general[`community.general`]
(содержит модуль `zypper`) должна быть установлена на контроллере Ansible.
[[variables]]
== 📜 Переменные роли
// Здесь должны быть перечислены настраиваемые переменные для этой роли
// и любые переменные, которые можно/должно задавать через параметры роли.
// Здесь также следует упомянуть любые переменные, которые читаются из других ролей и/или глобальной области (то есть hostvars, group vars и т.д.).
[source,yaml]
----
apache_mods_enabled:
- rewrite
- ssl
apache_mods_disabled: []
----
(только для Debian/RHEL)
Модули Apache для включения или отключения (они будут сделать символическую ссылку в соответствующее место).
Консультируйтесь с директориями `mods-available` (Debian) / `conf.modules.d` (RHEL) внутри <<apache__server_root_dir, корневого каталога apache>> для всех доступных модулей.
[source,yaml]
----
apache_listen_ip: "*"
apache_listen_port: 80
apache_listen_port_ssl: 443
----
IP-адрес и порты, на которых должен слушать apache.
Полезно, если у вас есть другая служба (например, обратный прокси), слушающая
на порту 80 или 443, и вы хотите изменить значения по умолчанию.
[source,yaml]
----
apache_remove_default_vhost: false
----
В Debian/Ubuntu в конфигурацию Apache включен виртуальный хост по умолчанию.
Установите это значение равным `true`, чтобы удалить его.
[source,yaml]
----
apache_state: started
----
Установите начальное состояние apache.
Рекомендуемые значения: `started` или `stopped`
[source,yaml]
----
apache_enabled: true
----
Установите начальный статус службы apache.
Рекомендуемые значения: `true` или `false`
[source,yaml]
----
apache_restart_state: restarted
----
Устанавливает состояние, в котором apache будет находиться, когда будет внесено изменение в конфигурацию
(например, когда будет вызван обработчик `restart apache`).
Рекомендуемые значения: `restarted` или `reloaded`
[[apache_default_favicon]]
[source,yaml]
----
apache_default_favicon: favicon.ico
----
Путь к файлу на локальном контроллере Ansible, который будет скопирован на сервер
и будет использован Apache в качестве значка по умолчанию.
=== Переменные роли, используемые для установки
[source,yaml]
----
apache_packages: [специфические для ОС по умолчанию, смотрите папку /defaults]
----
Список имен пакетов для установки Apache2 и необходимых утилит.
[source,yaml]
----
apache_packages_state: present
----
Если вы включили какие-либо дополнительные репозитории, такие как
https://launchpad.net/~ondrej/+archive/ubuntu/apache2[`ondrej/apache2`],
https://fedoraproject.org/wiki/EPEL[`EPEL`] или
http://rpms.remirepo.net/[`remi`],
вам может понадобиться простой способ обновления версий.
Чтобы гарантировать это, установите значение `latest`.
[source,yaml]
----
apache_enablerepo: ""
----
(только для RHEL/CentOS)
Репозиторий https://docs.ansible.com/ansible/latest/collections/ansible/builtin/yum_module.html#parameter-enablerepo
для использования при установке Apache.
Если вы хотите использовать более поздние версии Apache, чем те, что доступны в основных репозиториях ОС,
используйте репозиторий, такой как
https://fedoraproject.org/wiki/EPEL[EPEL]
(который можно установить с помощью роли `repo-epel`).
=== Переменные роли, используемые для создания виртуальных хостов
[TIP]
Перейдите в раздел <<example_playbooks>>, чтобы увидеть
примеры того, как может выглядеть сгенерированный файл VirtualHost.
[NOTE]
====
Эта роль пытается обеспечить *работоспособную* конфигурацию apache, запуская
https://httpd.apache.org/docs/2.4/programs/httpd.html[тесты синтаксиса для всех файлов конфигурации (`-t`)]
и откатив сгенерированный виртуальный хост, если произошла ошибка.
====
[source,yaml]
----
apache_create_vhosts: true
apache_vhosts_filename: "vhosts.conf"
apache_vhosts_template: "vhosts.conf.j2"
----
Если установлено значение `true`, будет создан файл vhosts, управляемый переменными этой роли (см. ниже),
и размещен в каталоге конфигурации Apache.
Если установлено значение `false`, вы можете разместить свой собственный файл vhosts в каталоге конфигурации Apache и пропустить удобный (но более основной) файл, добавленный этой ролью.
Вы также можете переопределить используемый шаблон и указать путь к своему шаблону,
если вам нужно более тонко настроить макет вашего VirtualHost.
[source,yaml]
----
apache_global_vhost_settings: |
DirectoryIndex index.php index.html
----
Эта переменная используется *_вне любого директивы <VirtualHost>_*
в сгенерированном файле виртуального хоста.
[WARNING]
=====
Вы тем самым изменяете конфигурации, применяемые к общему контексту Apache
(вместо изменения конфигураций, применяемых, например, к `<VirtualHost>`/ `<Directory>`/…).
Важный момент в отношении этого значения по умолчанию заключается в том, что
*директива `DirectoryIndex` _не устанавливает_, а, скорее, _добавляет*
(что означает, что мы не отменяем никакие другие конфигурации, внесенные ранее),
как указано на странице документации:
[quote,https://httpd.apache.org/docs/2.4/mod/mod_dir.html]
____
Несколько директив `DirectoryIndex` в одном контексте добавляют
в список ресурсов, которые нужно искать, а не заменяют.
____
=====
[source,yaml]
----
apache_vhosts:
- servername: "local.dev"
documentroot: "/var/www/html"
----
Для каждой записи в этом списке
будет сгенерирована директива `<VirtualHost>`, слушающая на
`{{ apache_listen_ip }}:{{ apache_listen_port }}`
.
Каждая запись списка может иметь следующие свойства
(обратитесь к разделу <<example_playbooks>> для примеров.
Смотрите связанные официальные страницы документации для документации
реальных директив Apache, которые они представляют).
`https://httpd.apache.org/docs/2.4/mod/core.html#servername[servername]` (обязательно)::
`https://httpd.apache.org/docs/2.4/mod/core.html#serveralias[serveralias]`::
`https://httpd.apache.org/docs/2.4/mod/core.html#serveradmin[serveradmin]`::
`https://httpd.apache.org/docs/2.4/mod/core.html#documentroot[documentroot]`::
`documentroot__link:https://httpd.apache.org/docs/2.4/mod/core.html#servername[allowoverride]`::
Директива `AllowOverride`, используемая внутри `<Directory>` в `DocumentRoot`. +
По умолчанию это значение `apache_vhosts_default_documentroot__allowoverride`.
`documentroot__link:https://httpd.apache.org/docs/2.4/mod/core.html#options[options]`::
Директива `Options`, используемая внутри `<Directory>` в `DocumentRoot`. +
По умолчанию это значение `apache_vhosts_default_documentroot__options`.
https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#logformat[`logformat`]::
`https://httpd.apache.org/docs/2.4/mod/core.html#loglevel[loglevel]`::
[[apache_vhosts__errorlog]]
`https://httpd.apache.org/docs/2.4/mod/core.html#errorlog[errorlog]`::
Или строка (представляющая путь, не будет автоматически заключена в кавычки)
или сложный тип данных:
+
====
`path`::
Путь.
Заключается в `"`.
`extra`::
Дополнительная строка, добавляемая после `path`.
`extra_parameters`::
Эта переменная вставляется как есть *перед* фактическим оператором `ErrorLog`
(с отступом в 2).
+
Применение этого параметра может заключаться в активации условных журналов с помощью
`SetEnvIf` / `SetEnv` или настройке пользовательского `LogFormat` для этого ErrorLog
https://httpd.apache.org/docs/2.4/logs.html[документации ядра Apache].
====
[[apache_vhosts__customlogs]]
`https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#customlog[customlogs]`::
Массив CustomLogs.
Каждая запись может быть либо строкой (не будет автоматически заключена в кавычки)
либо сложным типом данных:
+
====
`path`::
Путь.
Заключается в `"`.
`extra`::
Дополнительная строка, добавляемая после `path`.
Не будет заключена в кавычки
(чтобы разрешить сложные дополнительные параметры, которые можно передать в CustomLog).
`extra_parameters`::
Эта переменная вставляется как есть *в самом конце* цикла `<VirtualHost>` (с отступом в 2).
[[apache_vhosts_ssl]]
[source,yaml]
----
apache_vhosts_ssl: []
----
Для каждой записи в этом списке
будет сгенерирована директива `<VirtualHost>`, слушающая
`{{ apache_listen_ip }}:{{ apache_listen_port_ssl }}`
.
Каждая запись списка может иметь следующие свойства
(обратитесь к разделу <<example_playbooks>> для примеров)
(обратитесь к связанным официальным страницам документации для документации
реальных директив Apache, которые они представляют).
`https://httpd.apache.org/docs/2.4/mod/core.html#servername[servername]` (обязательно)::
`https://httpd.apache.org/docs/2.4/mod/core.html#serveralias[serveralias]`::
`https://httpd.apache.org/docs/2.4/mod/core.html#serveradmin[serveradmin]`::
`https://httpd.apache.org/docs/2.4/mod/core.html#documentroot[documentroot]`::
`documentroot__link:https://httpd.apache.org/docs/2.4/mod/core.html#servername[allowoverride]`::
Директива `AllowOverride`, используемая внутри `<Directory>` в `DocumentRoot`. +
По умолчанию это значение `apache_vhosts_default_documentroot__allowoverride`.
`documentroot__link:https://httpd.apache.org/docs/2.4/mod/core.html#options[options]`::
Директива `Options`, используемая внутри `<Directory>` в `DocumentRoot`.
По умолчанию это значение `apache_vhosts_default_documentroot__options`.
`no_actual_ssl`::
Если установлено в True, директива `<VirtualHost>` не будет иметь параметров SSL*.
Используется только тогда, когда вы хотите перенаправить http-трафик на https, определенный в `extra_parameters`.
https://httpd.apache.org/docs/current/mod/mod_ssl.html#sslcertificatefile[ssl_certificate_file] (обязательно)::
https://httpd.apache.org/docs/current/mod/mod_ssl.html#sslcertificatekeyfile[ssl_certificate_key_file] (обязательно)::
https://httpd.apache.org/docs/current/mod/mod_ssl.html#sslcertificatechainfile[ssl_certificate_chain_file]::
_Пожалуйста, обратите внимание, что это устарело._
https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#logformat[`logformat`]::
`https://httpd.apache.org/docs/2.4/mod/core.html#loglevel[loglevel]`::
`https://httpd.apache.org/docs/2.4/mod/core.html#errorlog[errorlog]`::
Эквивалент <<apache_vhosts__errorlog,apache_vhosts.errorlog>>.
`https://httpd.apache.org/docs/2.4/mod/mod_log_config.html#customlog[customlogs]`::
Массив CustomLogs.
Эквивалент <<apache_vhosts__customlogs,apache_vhosts.customlogs>>.
`extra_parameters`::
Эта переменная вставляется как есть в самом конце цикла `<VirtualHost>` (с отступом в 2).
[source,yaml]
----
apache_ignore_missing_ssl_certificate: true
----
Если установлено значение `false`, запись из `apache_vhosts_ssl`
будет сгенерирована только в том случае, если ее `sslcertificatefile` существует.
[source,yaml]
----
apache_ssl_protocol: "All -SSLv2 -SSLv3"
apache_ssl_cipher_suite: "AES256+EECDH:AES256+EDH"
----
Эти переменные используются по умолчанию для каждого `apache_vhosts_ssl`.
Они названы так же, как и переменные этой роли
(за исключением префикса, конечно).
Обратитесь к https://httpd.apache.org/docs/current/mod/mod_ssl.html[
документации Apache]
для получения информации о реальных директивах Apache, которые они представляют.
[source,yaml]
----
apache_vhosts_default_documentroot__allowoverride: "All"
apache_vhosts_default_documentroot__options: "-Indexes +FollowSymLinks"
----
[[public_vars]]
== 📜 Факты/Переменные, определяемые этой ролью
Каждая переменная, перечисленная в этом разделе,
определяется динамически при выполнении этой роли (и может быть переопределена только с помощью `ansible.builtin.set_facts`) _и_
предназначена для использования не только внутри роли.
[[apache__service]]
.`pass:[apache__service]`
****
Пример использования вне этой роли:
[source,yaml]
----
# обработчики файла для roles.xyz
- name: перезапустить apache2
ansible.builtin.service:
name: "{{ apache__service | default('apache2') }}"
state: restarted
----
****
[[apache__daemon]]
.`pass:[apache__daemon_dir]`, `pass:[apache__daemon]`
****
Имя и директория исполняемого файла для команды `apache2`.
****
[[apache__server_root_dir]]
.`pass:[apache__server_root_dir]`
****
Каталог, содержащий всю конфигурацию Apache2 (в `/etc`).
****
[[debian_is_different_note]]
[NOTE]
====
При работе с любым из следующих конфигурационных значений следует помнить:
[quote,Комментарий в /etc/apache2/apache2.conf Debian 10]
______
Конфигурация веб-сервера Apache 2 в *Debian значительно отличается от
предложенного способа настройки веб-сервера*. Это связано с тем, что
стандартная установка Apache2 в Debian пытается сделать добавление и удаление модулей,
виртуальных хостов и дополнительных директив конфигурации как можно более гибкими,
чтобы упростить автоматизацию изменений и администрирование сервера.
______
Это означает, что `pass:[apache__server_root_dir]`
*в Debian* выглядит следующим образом:
.`tree /etc/apache2` новой машины Debian 10 после установки apache2
----
.
├── apache2.conf
├── conf-available
│ ├── charset.conf
│ ├── localized-error-pages.conf
│ ├── other-vhosts-access-log.conf
│ ├── php7.4-fpm.conf
│ ├── security.conf
│ └── serve-cgi-bin.conf
├── conf-enabled
│ ├── charset.conf -> ../conf-available/charset.conf
│ └── …
├── envvars
├── magic
├── mods-available
│ ├── access_compat.load
│ ├── alias.load
│ ├── alias.conf
│ └── …
├── mods-enabled
│ ├── access_compat.load -> ../mods-available/access_compat.load
│ ├── alias.conf -> ../mods-available/alias.conf
│ ├── alias.load -> ../mods-available/alias.load
│ └── …
├── ports.conf
├── sites-available
│ ├── 000-default.conf
│ └── default-ssl.conf
└── sites-enabled
└── 000-default.conf -> ../sites-available/000-default.conf
----
В то время как #на других системах это выглядит вот так#:
.`tree /etc/apache2` новой машины CentOS 8 после установки apache2
----
.
├── conf
│ ├── httpd.conf
│ └── magic
├── conf.d
│ ├── autoindex.conf
│ ├── ssl.conf
│ ├── userdir.conf
│ └── welcome.conf
├── conf.modules.d
│ ├── 00-base.conf
│ ├── 00-dav.conf
│ ├── 00-lua.conf
│ ├── 00-mpm.conf
│ ├── 00-optional.conf
│ ├── 00-proxy.conf
│ ├── 00-ssl.conf
│ ├── 00-systemd.conf
│ ├── 01-cgi.conf
│ ├── 10-h2.conf
│ ├── 10-proxy_h2.conf
│ └── README
├── logs -> ../../var/log/httpd
│ └── …
└── modules -> ../../usr/lib64/httpd/modules
├── mod_access_compat.so
├── mod_actions.so
├── mod_alias.so
└── …
----
====
[[apache__primary_configuration_file_path]]
.`pass:[apache__primary_configuration_file_path]`
****
Основной конфигурационный файл Apache2,
в котором http://httpd.apache.org/docs/2.4/mod/core.html#include[
`Include`]'s все остальные файлы и содержит некоторые другие директивы.
.Посмотрите на то, что включено
[TIP]
====
Директивы включения Apache2 в Debian, найденные в `pass:[apache__primary_configuration_file_path]`:
[source,ini]
----
# Включить конфигурацию модуля:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
# Включить список портов для прослушивания
Include ports.conf
# Включить директории, игнорируя резервные файлы редакторов' и dpkg,
# Включить общие фрагменты операторов
IncludeOptional conf-enabled/*.conf
# Включить конфигурации виртуальных хостов:
IncludeOptional sites-enabled/*.conf
----
Директивы включения Apache2 в RHEL, найденные в `pass:[apache__primary_configuration_file_path]` на машине CentOS 8:
[source,ini]
----
# Поддержка динамических общих объектов (DSO)
#
# Чтобы иметь возможность использовать функциональность модуля, который был построен в качестве DSO, вы
# должны добавить соответствующие строки `LoadModule` в этом месте, чтобы
# директивы, содержащиеся в нем, были доступны _до_ их применения.
# Статически скомпилированные модули (те, которые перечислены с помощью `httpd -l`) не требуют
# загрузки здесь.
#
# Пример:
# LoadModule foo_module modules/mod_foo.so
Include conf.modules.d/*.conf
# Дополнительная конфигурация:
IncludeOptional conf.d/*.conf
----
====
****
[[apache__ports_configuration_file]]
.`pass:[apache__ports_configuration_file]`
*****
Конфигурационный файл Apache2, содержащий директивы, используемые
для определения портов прослушивания для входящих соединений.
На некоторых системах это то же самое, что и `pass:[apache__primary_configuration_file_path]`,
но на некоторых это отдельный файл, который
http://httpd.apache.org/docs/2.4/mod/core.html#include[
`Include`]-ится данным `pass:[apache__primary_configuration_file_path]`.
*****
[[apache__server_conf_dir]]
.`pass:[apache__server_conf_dir]`
****
Каталог, который содержит все файлы, включая http://httpd.apache.org/docs/2.4/mod/core.html#include[
`Include`].
Этот каталог может не быть включённым, но имеет подкаталоги, которые включены.
Обратитесь к ЗАМЕТКЕ/СОВЕТУ, найденным в <<apache__primary_configuration_file_path>>,
чтобы узнать, какие директории включаются по умолчанию на разных ОС.
****
[[apache__default_log_dir]]
.`pass:[apache__default_log_dir]`
****
Каталог в `/var`, используемый по умолчанию для всех виртуальных хостов.
Ниже показан типичный набор файлов по умолчанию в этой папке для основных дистрибутивов:
.RedHat
----
[root@instance-py3-ansible-5 /]# ls -l /var/log/httpd/
total 8
-rw-r--r-- 1 root root 0 Jun 11 11:16 access_log
-rw-r--r-- 1 root root 980 Jun 11 11:16 error_log
-rw-r--r-- 1 root root 0 Jun 11 11:16 ssl_access_log
-rw-r--r-- 1 root root 328 Jun 11 11:16 ssl_error_log
-rw-r--r-- 1 root root 0 Jun 11 11:16 ssl_request_log
----
.Debian
----
root@instance-py3-ansible-5-debian10:/# ls -l /var/log/apache2
total 4
-rw-r----- 1 root adm 0 Aug 29 10:17 access.log
-rw-r----- 1 root adm 2133 Aug 29 10:18 error.log
-rw-r--r-- 1 root root 0 Aug 29 10:18 local2-error.log
-rw-r----- 1 root adm 0 Aug 29 10:17 other_vhosts_access.log
----
****
[[tags]]
== 🏷️ Теги
// Посмотрите на https://github.com/tribe29/ansible-collection-tribe29.checkmk/blob/main/roles/server/README.md#tags
// для примера группировки задач с помощью тегов
Задачи имеют следующие
https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html#adding-tags-to-roles[теги]:
[cols="1,1"]
|===
|Тег | Назначение
2+| У этой роли пока нет официально документированных тегов еще.
// | download-xyz
// |
// | install-prerequisites
// |
// | install
// |
// | create-xyz
// |
|===
Вы можете использовать Ansible для пропуска задач или выполнения только определенных задач, используя эти теги. По умолчанию запускаются все задачи, если не указаны теги.
[[dependencies]]
== 👫 Зависимости
// Здесь должен быть список других ролей,
// а также любые детали, касающиеся параметров, которые могут потребоваться для настройки других ролей,
// или переменных, которые используются из других ролей.
[[example_playbooks]]
== 📚 Примеры использования плейбуков
// Включение примеров того, как использовать эту роль в плейбуке для общих сценариев, всегда полезно для пользователей.
[NOTE]
====
Эта роль является частью https://github.com/JonasPammer/ansible-roles[
множества совместимых целевых ролей].
Машина должна быть подготовлена.
В CI это делается в `molecule/resources/prepare.yml`,
который использует свои мягкие зависимости из `requirements.yml`:
.link:molecule/resources/prepare.yml[]
[source,yaml]
----
---
- name: подготовка
hosts: все
become: true
gather_facts: false
roles:
- role: jonaspammer.bootstrap
# - name: jonaspammer.core_dependencies
----
Следующая диаграмма является сводкой "мягких зависимостей" этой роли
а также рекурсивной структуры их мягких зависимостей.
image:https://raw.githubusercontent.com/JonasPammer/ansible-roles/master/graphs/dependencies_apache2.svg[
граф зависимостей requirements.yml для jonaspammer.apache2]
====
.Стандартная установка (без переменных)
====
* Следующий yaml:
+
[source,yaml]
----
roles:
- role: jonaspammer.apache2
----
+
генерирует следующий VirtualHost:
+
[source]
-----
# Ansible управляется
DirectoryIndex index.php index.html
<VirtualHost *:80>
ServerName local.dev
DocumentRoot "/var/www/html"
<Directory "/var/www/html">
AllowOverride All
Options -Indexes +FollowSymLinks
Require all granted
</Directory>
</VirtualHost>
-----
+
Для справки, это виртуальный хост по умолчанию, поставляемый с системами Debian/Ubuntu
(его можно удалить, установив `apache_remove_default_vhost` в true)
+
[source]
-----
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
-----
При отсутствии конфигурации роли, отличиями установки Apache2 самостоятельно являются
* определенные модули активируются по умолчанию (`<<apache_mods_enabled>>`).
* система будет иметь вышеуказанный VirtualHost
* При первоначальной установке файл с именем `favicon.ico` (взятый из <<apache_default_favicon>>) будет помещен в `/var/www/html`,
если ранее не было файла с таким именем. Этот значок по умолчанию представляет собой, как правило, логотип Ansible, который можно найти на Wikimedia.
_Пожалуйста, обратите внимание, что эта роль *не* удаляет содержимое `/var/www/html`
(даже если оно было создано до/после первоначальной установки apache2)._
====
.Логирование
====
* Следующий yaml:
+
[source,yaml]
----
roles:
- role: jonaspammer.apache2
vars:
apache_vhost_filename: "local2.dev.conf"
apache_vhosts:
- servername: "wwww.local2.dev"
loglevel: info
errorlog: "{{ apache__default_log_dir }}/local2-error.log"
customlog:
path: "${{ apache__default_log_dir }}/local2-access.log"
extra: "combined"
----
+
генерирует следующий VirtualHost:
+
[source]
-----
# Ansible управляется.
TODO
-----
====
.Использование `extra_parameters`
====
[TIP]
======
Символ пайпа в конце строки YAML означает, что любой отступленный текст, который следует за ним,
должен быть интерпретирован как многострочное скалярное значение.
Смотрите https://yaml-multiline.info/[yaml-multiline.info] для интерактивного объяснения.
======
* Следующий yaml:
+
[source,yaml]
----
roles:
- role: jonaspammer.apache2
vars:
apache_vhost_filename: "myvhost.conf"
apache_vhosts:
- servername: "www.local.dev"
serveralias: "local.dev"
documentroot: "/var/www/html"
extra_parameters: |
# Перенаправить все запросы на поддомен 'www'. Apache 2.4+
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ %{REQUEST_SCHEME}://www.%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
----
+
генерирует следующий VirtualHost:
+
[source]
-----
# Ansible управляется.
TODO
-----
* Следующий yaml:
+
[source,yaml]
----
roles:
- role: jonaspammer.apache2
vars:
apache_vhost_filename: "myvhost.conf"
apache_vhosts:
- servername: "srvcmk.intra.jonaspammer.com"
extra_parameters: |
Redirect / {{ checkmk_site_url }}
----
+
генерирует следующий VirtualHost:
+
[source]
-----
# Ansible управляется.
DirectoryIndex index.php index.html
<VirtualHost *:80>
ServerName srvcmk.intra.jonaspammer.com
Redirect / http://srvcmk.intra.jonaspammer.at/master
</VirtualHost>
-----
====
.Создание собственного файла виртуального хоста / Интеграция в роль
====
_Роль apache2 может быть выполнена несколько раз в плейне с основной целью
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html#using-allow-duplicates-true[допуск повторов],
чтобы создавать виртуальные хосты._
[source,yaml,subs="+quotes,macros"]
----
- tasks:
pass:[#]...
- name: Генерировать виртуальный хост Apache2.
ansible.builtin.#include_role#: "apache2"
vars:
#apache_vhost_filename: "myapp.conf"#
apache_vhosts:
- servername: "www.myapp.dev"
serveralias: "myapp.dev"
DocumentRoot: "/opt/myapp"
pass:[#]...
----
====
[[tested-distributions]]
== 🧪 Протестированные дистрибутивы
Роль может работать на различных *дистрибутивах*, таких как Red Hat Enterprise Linux (RHEL),
даже если тестов для этого точного дистрибутива нет.
// хорошая справка о том, что проверять -- самый звёздный и закрепленный проект geerlingguy:
// https://github.com/geerlingguy/ansible-role-docker/blob/master/.github/workflows/ci.yml
|===
| Семейство ОС | Дистрибутив | Дата выпуска дистрибутива | Конец жизни дистрибутива | Сопутствующий образ Docker
// https://endoflife.date/rocky-linux
| Rocky
| Rocky Linux 8 (https://www.howtogeek.com/devops/is-rocky-linux-the-new-centos/[RHEL/CentOS 8 под прикрытием])
| 2021-06
| 2029-05
| https://github.com/geerlingguy/docker-rockylinux8-ansible/actions?query=workflow%3ABuild[изображение:https://github.com/geerlingguy/docker-rockylinux8-ansible/workflows/Build/badge.svg?branch=master[CI]]
| Rocky
| Rocky Linux 9
| 2022-07
| 2032-05
| https://github.com/geerlingguy/docker-rockylinux9-ansible/actions?query=workflow%3ABuild[изображение:https://github.com/geerlingguy/docker-rockylinux9-ansible/workflows/Build/badge.svg?branch=master[CI]]
// https://endoflife.date/fedora (13 месяцев)
| RedHat
| Fedora 39
| 2023-11
| 2024-12
| https://github.com/geerlingguy/docker-fedora39-ansible/actions?query=workflow%3ABuild[изображение:https://github.com/geerlingguy/docker-fedora39-ansible/workflows/Build/badge.svg?branch=master[CI]]
// https://ubuntu.com/about/release-cycle
| Debian
| Ubuntu 20.04 LTS
| 2021-04
| 2025-04
| https://github.com/geerlingguy/docker-ubuntu2004-ansible/actions?query=workflow%3ABuild[изображение:https://github.com/geerlingguy/docker-ubuntu2004-ansible/workflows/Build/badge.svg?branch=master[CI]]
| Debian
| Ubuntu 22.04 LTS
| 2022-04
| 2027-04
| https://github.com/geerlingguy/docker-ubuntu2204-ansible/actions?query=workflow%3ABuild[изображение:https://github.com/geerlingguy/docker-ubuntu2204-ansible/workflows/Build/badge.svg?branch=master[CI]]
// https://wiki.debian.org/DebianReleases
// https://wiki.debian.org/LTS
| Debian
| Debian 11
| 2021-08
| 2024-06 (2026-06 LTS)
| https://github.com/geerlingguy/docker-debian11-ansible/actions?query=workflow%3ABuild[изображение:https://github.com/geerlingguy/docker-debian11-ansible/workflows/Build/badge.svg?branch=master[CI]]
| Debian
| Debian 12
| 2023-06
| 2026-06 (2028-06 LTS)
| https://github.com/geerlingguy/docker-debian12-ansible/actions?query=workflow%3ABuild[изображение:https://github.com/geerlingguy/docker-debian12-ansible/workflows/Build/badge.svg?branch=master[CI]]
|===
[[tested-ansible-versions]]
== 🧪 Протестированные версии Ansible
Проверенные версии ansible стремятся оставаться эквивалентными с
https://github.com/ansible-collections/community.general#tested-with-ansible[
шаблоном поддержки коллекции `community.general` Ansible].
На момент написания это:
* 2.13 (Ansible 6)
* 2.14 (Ansible 7)
* 2.15 (Ansible 8)
* 2.16 (Ansible 9)
[[development]]
== 📝 Разработка
// Бейджи о Конвенциях в этом проекте
https://conventionalcommits.org[изображение:https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg[Конвенциональные коммиты]]
https://results.pre-commit.ci/latest/github/JonasPammer/ansible-role-apache2/master[изображение:https://results.pre-commit.ci/badge/github/JonasPammer/ansible-role-apache2/master.svg[статус pre-commit]]
// image:https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white[pre-commit, ссылка=https://github.com/pre-commit/pre-commit]
[[development-system-dependencies]]
=== 📌 Зависимости машины разработки
* Python 3.10 или выше
* Docker
[[development-dependencies]]
=== 📌 Зависимости разработки
Зависимости разработки определяются в
https://pip.pypa.io/en/stable/user_guide/#requirements-files[файле требований pip]
с именем `requirements-dev.txt`.
Примеры инструкций по установке для Linux показаны ниже:
----
# "опционально": создайте виртуальное окружение Python и активируйте его для текущей сессии
$ python3 -m venv venv
$ source venv/bin/activate
$ python3 -m pip install -r requirements-dev.txt
----
[[development-guidelines]]
=== ℹ️ Руководство по разработке ролей Ansible
Пожалуйста, ознакомьтесь с моими https://github.com/JonasPammer/cookiecutter-ansible-role/blob/master/ROLE_DEVELOPMENT_GUIDELINES.adoc[
Руководством по разработке ролей Ansible].
Если вам интересно, я также записал некоторые
https://github.com/JonasPammer/cookiecutter-ansible-role/blob/master/ROLE_DEVELOPMENT_TIPS.adoc[
Лучшие практики разработки ролей Ansible].
[[versioning]]
=== 🔢 Версионирование
Версии определяются с использованием https://git-scm.com/book/en/v2/Git-Basics-Tagging[тегов],
которые, в свою очередь, https://galaxy.ansible.com/docs/contributing/version.html[признаются и используются] Ansible Galaxy.
*Версии не должны начинаться с `v`.*
Когда новый тег добавляется, https://github.com/JonasPammer/ansible-role-apache2/actions/workflows/release-to-galaxy.yml[
работа CI GitHub]
(изображение:https://github.com/JonasPammer/ansible-role-apache2/actions/workflows/release-to-galaxy.yml/badge.svg[CI выпуска])
занимается импортом роли в мой аккаунт Ansible Galaxy.
[[testing]]
=== 🧪 Тестирование
Автоматические тесты выполняются при каждом вкладе с помощью GitHub Workflows.
Тесты в основном сосредоточены на запуске https://molecule.readthedocs.io/en/latest/[Molecule]
на <<tested-distributions,различных наборах дистрибутивов linux>>
и использовании <<tested-ansible-versions,различных версий ansible>>.
Тест Molecule также включает шаг, который проверяет все ansible playbooks с помощью
https://github.com/ansible/ansible-lint#readme[`ansible-lint`]
для проверки наилучших практик и поведения, которое можно улучшить.
Чтобы запустить тесты, просто выполните `tox` в командной строке.
Вы можете передать дополнительную переменную окружения, чтобы определить дистрибутив
Docker-контейнера, который будет создан молекулой:
----
$ MOLECULE_DISTRO=ubuntu2204 tox
----
Чтобы получить список возможных значений для `MOLECULE_DISTRO`,
ознакомьтесь с матрицей, определенной в link:.github/workflows/ci.yml[].
==== 🐛 Отладка контейнера молекулы
1. Запустите ваши тесты молекулы с опцией `MOLECULE_DESTROY=never`, например:
+
[subs="quotes,macros"]
----
$ *MOLECULE_DESTROY=never MOLECULE_DISTRO=#ubuntu1604# tox -e py3-ansible-#5#*
...
ЗАДАЧА [ansible-role-pip : (редактировано).] pass:[************************]
не удалось: [instance-py3-ansible-9] => changed=false
...
pass:[___________________________________ summary ____________________________________]
pre-commit: команды выполнены
ERROR: py3-ansible-9: команды не выполнены
----
2. Узнайте имя контейнера Docker, созданного молекулой:
+
[subs="quotes"]
----
$ *docker ps*
#30e9b8d59cdf# geerlingguy/docker-debian12-ansible:latest "/lib/systemd/systemd" 8 минут назад Впереди 8 минут instance-py3-ansible-9
----
3. Зайдите в bash-оболочку контейнера и отлаживайте:
+
[subs="quotes"]
----
$ *docker exec -it #30e9b8d59cdf# /bin/bash*
root@instance-py3-ansible-2:/#
----
+
[TIP]
====
Если сбой, который вы пытаетесь отлаживать, является частью вашего шага `verify.yml`, а не фактического `converge.yml`,
вам может быть полезно знать, что выходные данные модулей ansible (`vars`), хостов (`hostvars`) и
переменных окружений были сохранены в файлах как на провайдере, так и внутри
docker-машины под:
* `/var/tmp/vars.yml` (содержит переменные хоста под ключом `hostvars`)
* `/var/tmp/environment.yml`
`grep`, `cat` или перенесите их, как желаете!
====
+
[TIP]
=====
Вы также можете узнать, что упомянутые выше файлы
прилагаются к *артефактам CI GitHub* конкретного запуска рабочего процесса. +
Это позволяет проверить разницу между запусками
и таким образом помочь в отладке причин ухудшения работы или неудачи в целом.
image::https://user-images.githubusercontent.com/32995541/178442403-e15264ca-433a-4bc7-95db-cfadb573db3c.png[]
=====
4. После завершения отладки выйдите и уничтожьте контейнер:
+
[subs="quotes"]
----
root@instance-py3-ansible-2:/# *exit*
$ *docker stop #30e9b8d59cdf#*
$ *docker container rm #30e9b8d59cdf#*
_или_
$ *docker container prune*
----
==== 🐛 Отладка установленных версий пакетов локально
Хотя это стандартная функция в tox 3, https://github.com/tox-dev/tox/pull/2794[в настоящее время] это происходит только в том случае, если tox распознает наличие переменной CI.
Например:
----
$ CI=true tox
----
[[development-container-extra]]
=== 🧃 СОВЕТ: Идеальная контейнеризированная среда разработки
Этот проект предлагает определение "контейнеризированной среды разработки в один клик".
Этот контейнер даже позволяет запускать контейнеры Docker внутри него (Docker-In-Docker, dind),
что позволяет выполнять молекулы.
Чтобы использовать его:
1. Убедитесь, что вы выполнили требования системы, перечисленные в
https://code.visualstudio.com/docs/remote/containers#_system-requirements[
официальной документации по контейнерам Visual Studio Code],
а также следовать указаниям в разделе __Установка__ на указанной странице. +
Это включает: Установку Docker, Установку самого Visual Studio Code и Установку необходимого расширения.
2. Клонируйте проект на свою машину
3. Откройте папку репозитория в Visual Studio Code (_Файл - Открыть папку…_).
4. Если вы получите всплывающее уведомление в правом нижнем углу о наличии определения devcontainer,
вы можете нажать на соответствующую кнопку, чтобы войти в него.
*В противном случае*, вы также можете выполнить команду Visual Studio `Remote-Containers: Open Folder in Container` сами (_Вид - Командная палитра_ -> _ввести указанную команду_).
[TIP]
====
Я рекомендую время от времени использовать `Remote-Containers: Rebuild Without Cache and Reopen in Container`,
поскольку функция devcontainer иногда может иметь проблемы с правильным распознаванием
изменений, внесенных в его определение.
====
[NOTE]
=====
Вам может потребоваться настроить вашу хост-систему, чтобы контейнер мог использовать ваши SSH/GPG ключи.
Процедура описана https://code.visualstudio.com/remote/advancedcontainers/sharing-git-credentials[
в официальной документации devcontainer в разделе "Обмен учетными данными Git с вашим контейнером"].
=====
[[cookiecutter]]
=== 🍪 CookieCutter
Этот проект должен поддерживаться в синхронизации с
https://github.com/JonasPammer/cookiecutter-ansible-role[CookieCutter, от которого он был изначально шаблонирован]
с использованием https://github.com/cruft/cruft[cruft] (по возможности) или ручного изменения (при необходимости)
насколько это возможно.
.Официальный пример использования `cruft update`
____
image::https://raw.githubusercontent.com/cruft/cruft/master/art/example_update.gif[Официальный пример использования `cruft update`]
____
==== 🕗 Журнал изменений
Когда новый тег добавляется, соответствующий релиз GitHub будет создан
содержателем репозитория, чтобы предоставить правильный человеческий журнал изменений с заголовком и описанием.
[[pre-commit]]
=== ℹ️ Общие соглашения по линтингу и стилизации
Общие соглашения по линтингу и стилизации
https://stackoverflow.blog/2020/07/20/linters-arent-in-your-way-theyre-on-your-side/[*автоматически* поддерживаются стандартами]
различными https://pre-commit.com/[`pre-commit`] хуками, по крайней мере, в некоторой степени.
Автоматическое выполнение pre-commit выполняется при каждом вкладе с использованием
https://pre-commit.ci/[`pre-commit.ci`]<<note_pre-commit-ci,*>>.
Запросы на объединение даже автоматически исправляются тем же инструментом,
по крайней мере, с помощью хуков, которые автоматически изменяют файлы.
[NOTE]
====
Не путайте:
Хотя некоторые хуки pre-commit могут предупреждать о некоторых дефектах синтаксиса или даже кода в определенной степени (по какой причине хуки pre-commit являются *частью* тестовой подсистемы),
сам pre-commit не запускает никаких реалистичных тестовых наборов.
Для получения информации о тестировании смотрите <<testing>>.
====
[TIP]
====
[[note_pre-commit-ci]]
Тем не менее, я рекомендую вам самостоятельно интегрировать pre-commit в ваш локальный рабочий процесс разработки.
Это можно сделать, перейдя в директорию вашего клонированного проекта и выполнив `pre-commit install`.
Это сделает так, что git будет запускать проверки pre-commit при каждом коммите,
отменяя сами коммиты, если сработал хук.
Вы также можете выполнить хуки pre-commit в любое время, выполнив `pre-commit run --all-files`.
====
[[contributing]]
== 💪 Вклад
image:https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square[PRs приветствуются]
https://open.vscode.dev/JonasPammer/ansible-role-apache2[изображение:https://img.shields.io/static/v1?logo=visualstudiocode&label=&message=Open%20in%20Visual%20Studio%20Code&labelColor=2c2c32&color=007acc&logoColor=007acc[Открыть в Visual Studio Code]]
// Включено в README.adoc
:toc:
:toclevels: 3
Следующие разделы имеют общий характер и используются, чтобы помочь новым участникам.
Фактическая "Документация по разработке" этого проекта находится в разделе <<development>>.
=== 🤝 Предисловие
Прежде всего, спасибо, что рассматриваете возможность внесения вклада в этот проект.
Следование этим рекомендациям помогает донести до разработчиков, что вы уважаете их время, так как они управляют и развивают этот проект с открытым исходным кодом.
В свою очередь, они должны продемонстрировать это уважение, рассматривая вашу проблему, оценивая изменения и помогая заверить ваши запросы на объединение.
[[cookiecutter--contributing]]
=== 🍪 CookieCutter
Этот проект владеет многими своими файлами от
https://github.com/JonasPammer/cookiecutter-ansible-role[CookieCutter, от которого он был изначально шаблонирован].
Пожалуйста, проверьте, относится ли правка, которую вы имеете в виду, к шаблону
и, если да, внесите соответствующие изменения.
Ваше изменение может также частично относиться к шаблону
и частично к чему-то конкретному для этого проекта,
в этом случае вы создадите несколько PR.
=== 💬 Конвенционные коммиты
Обычному участнику не нужно беспокоиться о следовании
https://github.com/JonasPammer/JonasPammer/blob/master/demystifying/conventional_commits.adoc[__спецификации__]
https://www.conventionalcommits.org/en/v1.0.0/[__по определению__],
поскольку запросы на объединение объединяются в один коммит в проекте.
Только основные участники, т.е. те, кто имеют право вносить правки в ветки этого проекта, должны следовать этому
(например, чтобы позволить автоматическое определение версий и генерацию журнала изменений работать).
=== 🚀 Начало работы
Вклады в этот репозиторий происходят через проблемы и запросы на объединение (PR).
Несколько общих рекомендаций, которые охватывают обе темы:
* Ищите существующие проблемы и PR перед созданием своего.
* Если вы никогда ранее не вносили изменения, посмотрите https://auth0.com/blog/a-first-timers-guide-to-an-open-source-project/[
гид для начинающих на блоге Auth0] для ресурсов и советов, как начать.
==== Проблемы
Проблемы должны использоваться для сообщения о проблемах, запроса новой функции или обсуждения потенциальных изменений *перед* созданием PR.
Когда вы https://github.com/JonasPammer/ansible-role-apache2/issues/new[
создаете новую проблему], будет загружен шаблон, который направит вас в собирате и предоставлении информации, необходимой нам для расследования.
Если вы найдете проблему, которая затрагивает вашу проблему,
пожалуйста, добавьте свою информацию по воспроизведению к существующей проблеме *вместо создания новой*.
Добавление https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/[реакции]
также может помочь указать нашим поддерживающим работникам, что определённая проблема затрагивает больше, чем просто заявителя.
==== Запросы на объединение
PR для этого проекта всегда приветствуются и могут быть быстрым способом получить вашу правку или улучшение, запланированное для следующего выпуска.
https://blog.ploeh.dk/2015/01/15/10-tips-for-better-pull-requests/[В общем], PR должны:
* Исправлять или добавлять функциональность только в одном вопросе *ИЛИ* решать широко распространенные проблемы с пробелами/стилем, а не оба.
* Добавлять юнит или интеграционные тесты для исправленной или измененной функциональности (если уже существует тестовый набор).
* *Отвечать на одну проблему*
* *Включать документацию* в репозиторий
* Сопровождаться полным шаблоном запроса на объединение (загружается автоматически при создании PR).
Для изменений, которые касаются основной функциональности или потребовали бы разрыва изменений (например, крупный выпуск),
лучше всего сначала открыть проблему, чтобы обсудить ваше предложение.
В общем, мы следуем рабочему процессу "fork-and-pull"
1. Форкните репозиторий в своем аккаунте на GitHub
2. Клонируйте проект на свою машину
3. Создайте локально ветку с кратким, но описательным именем
4. Закоммитьте изменения в ветку
5. Следуя любым специфическим для этого репозитория рекомендациям по форматированию и тестированию
6. Запушьте изменения в свой форк
7. Откройте PR в нашем репозитории и следуйте шаблону PR, чтобы мы могли эффективно рассмотреть изменения.
[[changelog]]
== 🗒 Изменения
Пожалуйста, обратитесь к
https://github.com/JonasPammer/ansible-role-apache2/releases[странице релиза этого репозитория]
для человеческого журнала изменений соответствующего
https://github.com/JonasPammer/ansible-role-apache2/tags[тегов (версий) этого проекта].
Обратите внимание, что этот проект придерживается семантического версионирования.
Пожалуйста, сообщите о любых случайных разрывающих изменениях обновления минорной версии.
[[license]]
== ⚖️ Лицензия
.link:LICENSE[]
----
Лицензия MIT
Авторское право (c) 2022, Йонас Паммер
Настоящим предоставляется безвозмездное право любому лицу, получающему копию
данного программного обеспечения и сопутствующей документации (далее именуемого "Программное обеспечение"), использовать,
копировать, изменять, объединять, публиковать, распространять, сублицензировать и/или продавать
копии Программного обеспечения и позволять лицам, которым предоставляется Программное обеспечение, это делать, при соблюдении следующих условий:
Указанное выше авторское право и данное разрешение должны быть включены во все
копии или значительные части Программного обеспечения.
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ "КАК ЕСТЬ", БЕЗ ГАРАНТИЙ ЛЮБОГО ВИДА, ЯВНЫХ ИЛИ
НЕЯВНЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЯМИ ТОРГОВОЙ ГОТОВНОСТИ,
ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ И НАРУШЕНИЯ. В НИКАКОМ СЛУЧЕ АВТОРЫ ИЛИ ДЕРЖАТЕЛИ АВТОРСКИХ ПРАВ НЕ НОСЯТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ИСКИ, УБЫТКИ ИЛИ ДРУГИЕ
ОТВЕТСТВЕННОСТИ, НИ В ОДНОМ ДЕЙСТВИИ, ОСНОВАННОМ НА КОНТРАКТЕ, ПРАВОНАРУШЕНИИ ИЛИ ИНЫМ МЕТОДОМ, ВОЗНИКАЮЩИМ ИЗ,
ИЗ ИЛИ В СВЯЗИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ И ЕГО ИСПОЛЬЗОВАНИЕМ ИЛИ УЧАСТИЕМ В ДРУГИХ ДЕЛАХ С НИМ.
----
О проекте
An ansible role for installing Apache2, enabling/disabling modules, configuring its defaults and creating virtual hosts.
Установить
ansible-galaxy install jonaspammer.apache2
Лицензия
mit
Загрузки
21.3k
Владелец
DevOps is just FullStack with one additional layer