Compare commits
62 Commits
Author | SHA1 | Date | |
---|---|---|---|
8dd8c7685f | |||
398de4dcc8 | |||
1dabbe0f6f | |||
9b72646537 | |||
0c531fc919 | |||
06af6df556 | |||
3ca1df03ec | |||
37b5eca152 | |||
dd893a00cb | |||
b75c012ddd | |||
adb27b3be7 | |||
43f18ee37c | |||
bb79295969 | |||
5bc41c853f | |||
0474fb6047 | |||
24fbd9246f | |||
9a069a5c6b | |||
4709d4c0e7 | |||
220b967809 | |||
d8759bfa8c | |||
65ade98e04 | |||
52192b4d24 | |||
55ffb7055c | |||
2f21245787 | |||
74f04d975c | |||
ef8ba84ebc | |||
54582d0f1d | |||
29a9f07dbc | |||
2e6f7cc2f0 | |||
3a1c5d02e8 | |||
4110aa63c1 | |||
5c2eb4a087 | |||
258f88eedd | |||
764f1b5792 | |||
50feda89b3 | |||
1738030bf9 | |||
b6f55f1186 | |||
8fe1bebb4b | |||
f803c5c74b | |||
df19e70c88 | |||
c273781043 | |||
ac4bad6936 | |||
83ec1528ca | |||
2f86815728 | |||
349e64b54e | |||
e6e5b55f65 | |||
cbbc6f3ae4 | |||
8ba4e824fc | |||
cc7cb56aa3 | |||
2eca300dd0 | |||
48742d8a6f | |||
18d2f05e28 | |||
5e13584e7c | |||
ba86f05f5e | |||
03ebc12ac3 | |||
91445e4c60 | |||
bfad48fff1 | |||
f32cc1b6a0 | |||
589b269ae3 | |||
a2811c81ad | |||
aa6fa836ae | |||
d5a41badcf |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
gitea-data
|
||||||
|
jenkins-data
|
||||||
|
nginx
|
222
README.md
222
README.md
@ -0,0 +1,222 @@
|
|||||||
|
# Ansible Jenkins Deployment Pipeline
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
Этот репозиторий содержит проект Ansible, интегрированный с Jenkins, для автоматизации развёртывания двух веб-сайтов (`SiteA` и `SiteB`) и прокси-сервера (`Proxy`). Настройка обеспечивает балансировку нагрузки, автоматические проверки состояния (health checks) и динамическое обновление контента без ручного вмешательства. Дополнительно внедрены обработчики для перезапуска служб при изменении конфигурации и централизованное управление основным конфигурационным файлом Nginx через `group_vars`.
|
||||||
|
|
||||||
|
## Описание Компонентов
|
||||||
|
|
||||||
|
- **group_vars/**: Содержит файлы с переменными групп хостов. В `all.yml` определены общие переменные для всех ролей и хостов, включая параметры для Nginx и контент для сайтов.
|
||||||
|
|
||||||
|
- **roles/**: Основная директория с ролями Ansible.
|
||||||
|
|
||||||
|
- **firewall/**:
|
||||||
|
- **handlers/**: Содержит обработчики для перезапуска `firewalld`.
|
||||||
|
- **tasks/**: Задачи для установки и настройки `firewalld`, открытия необходимых портов.
|
||||||
|
- **vars/**: Переменные, используемые в роли `firewall`.
|
||||||
|
|
||||||
|
- **nginx_proxy/**:
|
||||||
|
- **handlers/**: Содержит обработчики для перезапуска Nginx.
|
||||||
|
- **tasks/**: Задачи для установки Nginx, создания директорий, деплоя конфигураций и тестирования конфигурации.
|
||||||
|
- **templates/**: Шаблоны конфигурационных файлов Nginx для прокси-сервера и страниц ошибок.
|
||||||
|
|
||||||
|
- **nginx_site/**:
|
||||||
|
- **handlers/**: Содержит обработчики для перезапуска Nginx.
|
||||||
|
- **tasks/**: Задачи для установки Nginx, создания корневых директорий сайтов, деплоя конфигураций и HTML файлов, а также тестирования конфигурации.
|
||||||
|
- **templates/**: Шаблоны конфигурационных файлов Nginx и HTML страниц для сайтов.
|
||||||
|
|
||||||
|
- **ssl_certificate/**:
|
||||||
|
- **handlers/**: Содержит обработчики для перезапуска Nginx после генерации SSL сертификатов.
|
||||||
|
- **tasks/**: Задачи для установки OpenSSL, создания директории для сертификатов и генерации самоподписанных сертификатов.
|
||||||
|
- **templates/**: Шаблоны или скрипты для генерации SSL сертификатов.
|
||||||
|
|
||||||
|
- **playbook.yml**: Основной Ansible playbook, который связывает все роли и определяет порядок их выполнения на соответствующих хостах.
|
||||||
|
|
||||||
|
- **inventory.yml**: Файл инвентаризации, содержащий информацию о целевых хостах и группах (`SiteA`, `SiteB`, `proxy`).
|
||||||
|
|
||||||
|
- **ansible.cfg**: Конфигурационный файл Ansible, определяющий пути к ролям и другие настройки.
|
||||||
|
|
||||||
|
- **jenkinsfile**: Скрипт для Jenkins Pipeline, который управляет процессом деплоя, включая расшифровку SSH ключей, передачу переменных и запуск Ansible playbook.
|
||||||
|
|
||||||
|
## Параметры и Их Назначение
|
||||||
|
|
||||||
|
### В `group_vars/all.yml`
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# group_vars/all.yml
|
||||||
|
ansible_python_interpreter: /usr/bin/python3.6
|
||||||
|
|
||||||
|
# Общие переменные для Nginx
|
||||||
|
nginx_worker_processes: auto
|
||||||
|
nginx_error_log: /var/log/nginx/error.log
|
||||||
|
nginx_error_log_level: warn
|
||||||
|
nginx_worker_connections: 1024
|
||||||
|
nginx_access_log: /var/log/nginx/access.log
|
||||||
|
nginx_keepalive_timeout: 65
|
||||||
|
nginx_types_hash_max_size: 2048
|
||||||
|
|
||||||
|
# Переменные для сайтов SiteA и SiteB
|
||||||
|
siteA:
|
||||||
|
site_title: "SiteA - Добро пожаловать"
|
||||||
|
site_h1: "Добро пожаловать на SiteA"
|
||||||
|
site_h2: "Дефолтный заголовок H2 для SiteA"
|
||||||
|
site_p: "Дефолтный параграф для SiteA"
|
||||||
|
site_domain: "siteA.example.com"
|
||||||
|
site_ip: "192.168.0.61"
|
||||||
|
|
||||||
|
siteB:
|
||||||
|
site_title: "SiteB - Добро пожаловать"
|
||||||
|
site_h1: "Добро пожаловать на SiteB"
|
||||||
|
site_h2: "Дефолтный заголовок H2 для SiteB"
|
||||||
|
site_p: "Дефолтный параграф для SiteB"
|
||||||
|
site_domain: "siteB.example.com"
|
||||||
|
site_ip: "192.168.0.62"
|
||||||
|
|
||||||
|
proxy:
|
||||||
|
proxy_domain: "proxy.example.com"
|
||||||
|
proxy_ip: "192.168.0.63"
|
||||||
|
|
||||||
|
# SSL переменные
|
||||||
|
ssl_cert_path: "/etc/nginx/ssl"
|
||||||
|
ssl_cert_file: "proxy.crt"
|
||||||
|
ssl_key_file: "proxy.key"
|
||||||
|
ssl_subject: "/C=RU/ST=Some-State/L=Some-City/O=Your Company/CN={{ proxy.proxy_domain }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### В `Jenkinsfile`
|
||||||
|
|
||||||
|
- **DEPLOY_TARGET**: Выбор цели развертывания (`SiteA`, `SiteB`, `All`).
|
||||||
|
- **ADDITIONAL_CONTENT_SITEA_H2**: Дополнительный контент для заголовка `<h2>` на SiteA.
|
||||||
|
- **ADDITIONAL_CONTENT_SITEA_P**: Дополнительный параграф `<p>` для SiteA.
|
||||||
|
- **ADDITIONAL_CONTENT_SITEB_H2**: Дополнительный контент для заголовка `<h2>` на SiteB.
|
||||||
|
- **ADDITIONAL_CONTENT_SITEB_P**: Дополнительный параграф `<p>` для SiteB.
|
||||||
|
|
||||||
|
### В Ролях
|
||||||
|
|
||||||
|
- **firewall/vars/main.yml**:
|
||||||
|
- `firewall_ports`: Список портов и протоколов, которые необходимо открыть в файрволе (например, SSH, HTTP, HTTPS).
|
||||||
|
|
||||||
|
- **nginx_proxy/vars/main.yml**:
|
||||||
|
- `ssl_cert_path`: Путь к директории, где будут храниться SSL сертификаты.
|
||||||
|
- `ssl_cert_file`: Имя SSL сертификата.
|
||||||
|
- `ssl_key_file`: Имя ключа SSL сертификата.
|
||||||
|
- `ssl_subject`: Параметры для генерации самоподписанного SSL сертификата.
|
||||||
|
|
||||||
|
## Как Использовать
|
||||||
|
|
||||||
|
### Настройка Инвентаря
|
||||||
|
|
||||||
|
Отредактируйте `inventory.yml`, указав правильные IP-адреса и пользователя для каждого хоста:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
all:
|
||||||
|
children:
|
||||||
|
SiteA:
|
||||||
|
hosts:
|
||||||
|
192.168.0.61:
|
||||||
|
ansible_user: ansible
|
||||||
|
ansible_python_interpreter: /usr/bin/python3.6
|
||||||
|
SiteB:
|
||||||
|
hosts:
|
||||||
|
192.168.0.62:
|
||||||
|
ansible_user: ansible
|
||||||
|
ansible_python_interpreter: /usr/bin/python3.6
|
||||||
|
proxy:
|
||||||
|
hosts:
|
||||||
|
192.168.0.63:
|
||||||
|
ansible_user: ansible
|
||||||
|
ansible_python_interpreter: /usr/bin/python3.6
|
||||||
|
```
|
||||||
|
|
||||||
|
### Настройка Переменных
|
||||||
|
|
||||||
|
Все переменные, используемые в проектах, определены в `group_vars/all.yml`. При необходимости, вы можете переопределить их через Jenkins параметры или добавить дополнительные переменные.
|
||||||
|
|
||||||
|
### Запуск Jenkins Pipeline
|
||||||
|
|
||||||
|
1. **Дешифровка SSH ключей**: Jenkins автоматически расшифровывает SSH ключи для доступа к серверам.
|
||||||
|
|
||||||
|
2. **Выбор Цели Развертывания**: Выберите, какой сайт (`SiteA`, `SiteB`) или все (`All`) нужно развернуть.
|
||||||
|
|
||||||
|
3. **Передача Дополнительных Переменных**: Введите дополнительные параметры контента для выбранных сайтов.
|
||||||
|
|
||||||
|
4. **Запуск Ansible Playbook**: Jenkins запускает Ansible playbook с переданными параметрами, развертывая конфигурации и контент на целевых хостах.
|
||||||
|
|
||||||
|
## Проверка и Отладка
|
||||||
|
|
||||||
|
Если при развертывании возникают ошибки:
|
||||||
|
|
||||||
|
1. **Просмотрите Логи Jenkins**: Получите подробную информацию об ошибках.
|
||||||
|
|
||||||
|
2. **Подключитесь к Целевым Серверам**: Проверьте статус служб и конфигурационных файлов.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl status nginx
|
||||||
|
systemctl status firewalld
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Проверьте Конфигурацию Nginx**: Убедитесь, что конфигурационные файлы корректны.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nginx -t
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Просмотрите Логи Nginx**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo journalctl -xeu nginx.service
|
||||||
|
sudo tail -n 100 /var/log/nginx/error.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример Запуска Playbook Локально
|
||||||
|
|
||||||
|
Для локального тестирования или отладки вы можете запустить playbook вручную:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook playbook.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Дополнительные Возможности
|
||||||
|
|
||||||
|
- **Автоматическое Тестирование Конфигураций**: Playbook включает задачи для тестирования конфигурации Nginx перед запуском службы, предотвращая запуск с ошибками.
|
||||||
|
|
||||||
|
- **Обработчики (Handlers)**: Автоматический перезапуск служб `nginx` и `firewalld` при изменении конфигурационных файлов.
|
||||||
|
|
||||||
|
- **Централизованное Управление Конфигурацией**: Основной конфигурационный файл Nginx управляется через шаблоны и переменные в `group_vars/all.yml`.
|
||||||
|
|
||||||
|
## Рекомендации и Лучшие Практики
|
||||||
|
|
||||||
|
1. **Безопасность**:
|
||||||
|
- Используйте Ansible Vault для защиты чувствительных данных.
|
||||||
|
- Убедитесь, что SSH ключи и другие секреты не попадают в систему контроля версий.
|
||||||
|
|
||||||
|
2. **Документация**:
|
||||||
|
- Поддерживайте актуальную документацию, описывающую структуру проекта и инструкции по развертыванию.
|
||||||
|
|
||||||
|
3. **Тестирование**:
|
||||||
|
- Используйте инструменты вроде [Molecule](https://molecule.readthedocs.io/en/latest/) для тестирования Ansible ролей.
|
||||||
|
- Внедрите проверку конфигураций перед применением изменений.
|
||||||
|
|
||||||
|
4. **Управление Конфигурациями**:
|
||||||
|
- Централизуйте общие конфигурационные файлы для облегчения управления и уменьшения дублирования.
|
||||||
|
- Используйте обработчики для автоматического применения изменений.
|
||||||
|
|
||||||
|
5. **Мониторинг и Логирование**:
|
||||||
|
- Внедрите системы мониторинга для отслеживания состояния сервисов.
|
||||||
|
- Анализируйте логи для своевременного обнаружения и устранения проблем.
|
||||||
|
|
||||||
|
## Заключение
|
||||||
|
|
||||||
|
Этот проект демонстрирует эффективное использование Ansible и Jenkins для автоматизации развёртывания веб-сайтов и прокси-сервера с учётом безопасности, надёжности и удобства управления. Следуя приведённым инструкциям и рекомендациям, вы сможете быстро адаптировать и расширять данное решение под свои нужды.
|
||||||
|
|
||||||
|
Если у вас возникнут дополнительные вопросы или потребуется помощь с настройкой, не стесняйтесь обращаться!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Примечания:**
|
||||||
|
|
||||||
|
- Убедитесь, что все переменные правильно определены и соответствуют вашим требованиям.
|
||||||
|
- При необходимости, обновите пути и имена файлов в соответствии с вашей инфраструктурой.
|
||||||
|
- Для улучшения безопасности рассмотрите использование Ansible Vault для хранения чувствительных данных, таких как SSH ключи и пароли.
|
||||||
|
|
||||||
|
https://cyeta12.online/nextcloud/s/5fnYWrw5qN8RdaY
|
124
ansible/Jenkinsfile
vendored
Normal file
124
ansible/Jenkinsfile
vendored
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
|
||||||
|
options {
|
||||||
|
ansiColor('xterm')
|
||||||
|
}
|
||||||
|
|
||||||
|
environment {
|
||||||
|
ANSIBLE_HOST_KEY_CHECKING = 'false'
|
||||||
|
VAULT_PASSWORD = credentials('vault_password')
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters {
|
||||||
|
choice(
|
||||||
|
name: 'DEPLOY_TARGET',
|
||||||
|
choices: ['SiteA', 'SiteB', 'proxy', 'SiteA&proxy', 'SiteB&proxy', 'All'],
|
||||||
|
description: 'Выберите цели для развертывания'
|
||||||
|
)
|
||||||
|
|
||||||
|
string(
|
||||||
|
name: 'ADDITIONAL_CONTENT_H2',
|
||||||
|
defaultValue: 'Новое сообщение',
|
||||||
|
description: 'Дополнительный <h2> контент'
|
||||||
|
)
|
||||||
|
string(
|
||||||
|
name: 'ADDITIONAL_CONTENT_P',
|
||||||
|
defaultValue: 'Дополнительный параграф',
|
||||||
|
description: 'Дополнительный <p> контент'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Decrypt SSH Key') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def tempDir = "/tmp/${UUID.randomUUID().toString()}"
|
||||||
|
env.TEMP_DIR = tempDir
|
||||||
|
sh "mkdir -p ${tempDir}"
|
||||||
|
|
||||||
|
def decryptedKeyFile = "${tempDir}/id_ed25519"
|
||||||
|
def vaultPassFile = "${tempDir}/vault_pass"
|
||||||
|
|
||||||
|
writeFile file: vaultPassFile, text: VAULT_PASSWORD
|
||||||
|
|
||||||
|
sh """
|
||||||
|
ansible-vault decrypt ./ansible/id_ed25519_vault --output=${decryptedKeyFile} --vault-password-file=${vaultPassFile}
|
||||||
|
"""
|
||||||
|
|
||||||
|
env.DECYPTED_KEY_FILE = decryptedKeyFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Deploy Site') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def selectedHosts
|
||||||
|
def extraVars = [
|
||||||
|
ansible_ssh_private_key_file: env.DECYPTED_KEY_FILE
|
||||||
|
]
|
||||||
|
|
||||||
|
switch(params.DEPLOY_TARGET) {
|
||||||
|
case 'SiteA':
|
||||||
|
selectedHosts = 'SiteA'
|
||||||
|
extraVars.siteA_h2 = params.ADDITIONAL_CONTENT_H2
|
||||||
|
extraVars.siteA_p = params.ADDITIONAL_CONTENT_P
|
||||||
|
break
|
||||||
|
case 'SiteB':
|
||||||
|
selectedHosts = 'SiteB'
|
||||||
|
extraVars.siteB_h2 = params.ADDITIONAL_CONTENT_H2
|
||||||
|
extraVars.siteB_p = params.ADDITIONAL_CONTENT_P
|
||||||
|
break
|
||||||
|
case 'proxy':
|
||||||
|
selectedHosts = 'proxy'
|
||||||
|
break
|
||||||
|
case 'SiteA&proxy':
|
||||||
|
selectedHosts = 'SiteA,proxy'
|
||||||
|
extraVars.siteA_h2 = params.ADDITIONAL_CONTENT_H2
|
||||||
|
extraVars.siteA_p = params.ADDITIONAL_CONTENT_P
|
||||||
|
break
|
||||||
|
case 'SiteB&proxy':
|
||||||
|
selectedHosts = 'SiteB,proxy'
|
||||||
|
extraVars.siteB_h2 = params.ADDITIONAL_CONTENT_H2
|
||||||
|
extraVars.siteB_p = params.ADDITIONAL_CONTENT_P
|
||||||
|
break
|
||||||
|
case 'All':
|
||||||
|
selectedHosts = 'SiteA,SiteB,proxy'
|
||||||
|
extraVars.siteA_h2 = params.ADDITIONAL_CONTENT_H2
|
||||||
|
extraVars.siteA_p = params.ADDITIONAL_CONTENT_P
|
||||||
|
extraVars.siteB_h2 = params.ADDITIONAL_CONTENT_H2
|
||||||
|
extraVars.siteB_p = params.ADDITIONAL_CONTENT_P
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
error "Неизвестный DEPLOY_TARGET: ${params.DEPLOY_TARGET}"
|
||||||
|
}
|
||||||
|
|
||||||
|
ansiblePlaybook(
|
||||||
|
playbook: 'ansible/playbook.yml',
|
||||||
|
inventory: "ansible/inventory.yml",
|
||||||
|
extraVars: extraVars,
|
||||||
|
limit: selectedHosts,
|
||||||
|
colorized: true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
script {
|
||||||
|
if (env.TEMP_DIR) {
|
||||||
|
sh "rm -rf ${env.TEMP_DIR}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
echo 'Deployment completed successfully.'
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
echo 'Deployment failed. Please check the logs for more details.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
ansible/ansible.cfg
Normal file
6
ansible/ansible.cfg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[defaults]
|
||||||
|
inventory = inventory.yml
|
||||||
|
roles_path = ./roles
|
||||||
|
host_key_checking = False
|
||||||
|
interpreter_python = /usr/bin/python3
|
||||||
|
force_color = true
|
34
ansible/group_vars/all.yml
Normal file
34
ansible/group_vars/all.yml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
ansible_python_interpreter: /usr/bin/python3.6
|
||||||
|
|
||||||
|
nginx_worker_processes: auto
|
||||||
|
nginx_error_log: /var/log/nginx/error.log
|
||||||
|
nginx_error_log_level: warn
|
||||||
|
nginx_worker_connections: 1024
|
||||||
|
nginx_access_log: /var/log/nginx/access.log
|
||||||
|
nginx_keepalive_timeout: 65
|
||||||
|
nginx_types_hash_max_size: 2048
|
||||||
|
|
||||||
|
siteA:
|
||||||
|
site_title: "SiteA - Добро пожаловать"
|
||||||
|
site_h1: "Добро пожаловать на SiteA"
|
||||||
|
site_h2: "{{ siteA_h2 }}"
|
||||||
|
site_p: "{{ siteA_p }}"
|
||||||
|
site_domain: "siteA.example.com"
|
||||||
|
site_ip: "192.168.0.61"
|
||||||
|
|
||||||
|
siteB:
|
||||||
|
site_title: "SiteB - Добро пожаловать"
|
||||||
|
site_h1: "Добро пожаловать на SiteB"
|
||||||
|
site_h2: "{{ siteB_h2 }}"
|
||||||
|
site_p: "{{ siteB_p }}"
|
||||||
|
site_domain: "siteB.example.com"
|
||||||
|
site_ip: "192.168.0.62"
|
||||||
|
|
||||||
|
proxy:
|
||||||
|
proxy_domain: "siteproxy.vlad"
|
||||||
|
proxy_ip: "192.168.0.63"
|
||||||
|
|
||||||
|
siteA_h2: "Новое сообщение для SiteA"
|
||||||
|
siteA_p: "Дополнительный параграф для SiteA"
|
||||||
|
siteB_h2: "Новое сообщение для SiteB"
|
||||||
|
siteB_p: "Дополнительный параграф для SiteB"
|
26
ansible/id_ed25519_vault
Normal file
26
ansible/id_ed25519_vault
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
63306262646434323632386463373239336566633737636235653430333132386537366564666234
|
||||||
|
6461393163343265306366313736313961373630313234340a323534616566666137616431386461
|
||||||
|
65373333643664633833613431666531353935646562396661623163343464663262396264643537
|
||||||
|
6261363038363062640a616431336162386465316639376662333066396535623735383032316538
|
||||||
|
36613839386139363661636536306361373231623432663331623766346262366230353432373538
|
||||||
|
34353032303461323533396438306561386332396266316565393930653038623361333163323736
|
||||||
|
63663734333034336337373632333565333633306361633335663365336161636439386563393736
|
||||||
|
33613262623862626161653466626339623861353566323864363231343365333666326163396538
|
||||||
|
30353265613330626261363038633762373531623864333937366361616465313961363536636430
|
||||||
|
37333739333661303865376137343931363563656362316339383033326539343135663936393931
|
||||||
|
36653363656535656334613264653932666231663930353931306662333833366534343365386136
|
||||||
|
61336538356164653433613930343137373534653732613830366439343061313166656533323230
|
||||||
|
65353938383563646162373232613632313332643765313135653730383864643539333732623739
|
||||||
|
32393239373735616463633830333136616438316361613336613336613766356538313534303939
|
||||||
|
64646262323164643336653761663338613036376365613565373561626366643765396564383665
|
||||||
|
38303135356639373762303139633862313833313063373737633336363939336438376239613536
|
||||||
|
65636539653335396464653363613339383862653862336630353364636162663237383163666134
|
||||||
|
30643865383533623461303630356631396135663265376264663637326136663161656638616332
|
||||||
|
32626636613138313232396636343032343666343039353533626131663235393235343966303662
|
||||||
|
30336364363361356339303466633165316330376336306130336536656134336130376137613663
|
||||||
|
34333136306638306332356363616165343536666239366532333630306535626532656438613030
|
||||||
|
37626535316532623134633238313733353566373630333834616132353061656530373763303531
|
||||||
|
33366536363333303966663663353865613532353164623762636531366535393465623239643765
|
||||||
|
39626662633164623734626433313132633532336161363036633434393432393934396663633531
|
||||||
|
6333
|
17
ansible/inventory.yml
Normal file
17
ansible/inventory.yml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
all:
|
||||||
|
children:
|
||||||
|
SiteA:
|
||||||
|
hosts:
|
||||||
|
192.168.0.61:
|
||||||
|
ansible_user: ansible
|
||||||
|
ansible_python_interpreter: /usr/bin/python3.6
|
||||||
|
SiteB:
|
||||||
|
hosts:
|
||||||
|
192.168.0.62:
|
||||||
|
ansible_user: ansible
|
||||||
|
ansible_python_interpreter: /usr/bin/python3.6
|
||||||
|
proxy:
|
||||||
|
hosts:
|
||||||
|
192.168.0.63:
|
||||||
|
ansible_user: ansible
|
||||||
|
ansible_python_interpreter: /usr/bin/python3.6
|
15
ansible/playbook.yml
Normal file
15
ansible/playbook.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
- hosts: all
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- firewall
|
||||||
|
|
||||||
|
- hosts: SiteA,SiteB
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- nginx_site
|
||||||
|
|
||||||
|
- hosts: proxy
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- ssl_certificate
|
||||||
|
- nginx_proxy
|
4
ansible/roles/firewall/handlers/main.yml
Normal file
4
ansible/roles/firewall/handlers/main.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
- name: Restart firewalld
|
||||||
|
systemd:
|
||||||
|
name: firewalld
|
||||||
|
state: restarted
|
24
ansible/roles/firewall/tasks/main.yml
Normal file
24
ansible/roles/firewall/tasks/main.yml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
- name: Install firewalld
|
||||||
|
zypper:
|
||||||
|
name: firewalld
|
||||||
|
state: present
|
||||||
|
notify:
|
||||||
|
- Restart firewalld
|
||||||
|
|
||||||
|
- name: Ensure firewalld is enabled and started
|
||||||
|
systemd:
|
||||||
|
name: firewalld
|
||||||
|
enabled: yes
|
||||||
|
state: started
|
||||||
|
notify:
|
||||||
|
- Restart firewalld
|
||||||
|
|
||||||
|
- name: Open specified firewall ports
|
||||||
|
firewalld:
|
||||||
|
port: "{{ item.port }}/{{ item.protocol }}"
|
||||||
|
permanent: yes
|
||||||
|
state: enabled
|
||||||
|
immediate: yes
|
||||||
|
loop: "{{ firewall_ports }}"
|
||||||
|
notify:
|
||||||
|
- Restart firewalld
|
4
ansible/roles/firewall/vars/main.yml
Normal file
4
ansible/roles/firewall/vars/main.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
firewall_ports:
|
||||||
|
- { port: 22, protocol: tcp }
|
||||||
|
- { port: 80, protocol: tcp }
|
||||||
|
- { port: 443, protocol: tcp }
|
2
ansible/roles/firewall_cmd/handlers/main.yml
Normal file
2
ansible/roles/firewall_cmd/handlers/main.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
- name: Restart firewalld
|
||||||
|
command: systemctl restart firewalld
|
28
ansible/roles/firewall_cmd/tasks/main.yml
Normal file
28
ansible/roles/firewall_cmd/tasks/main.yml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
- name: Install firewalld
|
||||||
|
zypper:
|
||||||
|
name: firewalld
|
||||||
|
state: present
|
||||||
|
notify:
|
||||||
|
- Restart firewalld
|
||||||
|
|
||||||
|
- name: Enable and start firewalld
|
||||||
|
command: systemctl enable --now firewalld
|
||||||
|
register: firewalld_enable
|
||||||
|
changed_when: "'Created symlink' in firewalld_enable.stdout or 'enabled' in firewalld_enable.stdout"
|
||||||
|
notify:
|
||||||
|
- Restart firewalld
|
||||||
|
|
||||||
|
- name: Open specified firewall ports permanently
|
||||||
|
loop: "{{ firewall_ports }}"
|
||||||
|
command: firewall-cmd --permanent --add-port={{ item.port }}/{{ item.protocol }}
|
||||||
|
register: firewalld_add_port
|
||||||
|
changed_when: "'success' in firewalld_add_port.stdout"
|
||||||
|
notify:
|
||||||
|
- Restart firewalld
|
||||||
|
|
||||||
|
- name: Reload firewalld rules
|
||||||
|
command: firewall-cmd --reload
|
||||||
|
register: firewalld_reload
|
||||||
|
changed_when: "'success' in firewalld_reload.stdout"
|
||||||
|
notify:
|
||||||
|
- Restart firewalld
|
4
ansible/roles/firewall_cmd/vars/main.yml
Normal file
4
ansible/roles/firewall_cmd/vars/main.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
firewall_ports:
|
||||||
|
- { port: 22, protocol: tcp }
|
||||||
|
- { port: 80, protocol: tcp }
|
||||||
|
- { port: 443, protocol: tcp }
|
4
ansible/roles/nginx_proxy/handlers/main.yml
Normal file
4
ansible/roles/nginx_proxy/handlers/main.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
- name: Restart Nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: restarted
|
47
ansible/roles/nginx_proxy/tasks/main.yml
Normal file
47
ansible/roles/nginx_proxy/tasks/main.yml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
- name: Install Nginx
|
||||||
|
zypper:
|
||||||
|
name: nginx
|
||||||
|
state: present
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Create directory for error pages
|
||||||
|
file:
|
||||||
|
path: /var/www/errors
|
||||||
|
state: directory
|
||||||
|
owner: nginx
|
||||||
|
group: nginx
|
||||||
|
mode: '0755'
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Deploy custom error page
|
||||||
|
template:
|
||||||
|
src: site_down.html.j2
|
||||||
|
dest: /var/www/errors/site_down.html
|
||||||
|
mode: '0644'
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Deploy Proxy Configuration
|
||||||
|
template:
|
||||||
|
src: proxy.conf.j2
|
||||||
|
dest: /etc/nginx/conf.d/proxy.conf
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Deploy Main Nginx Configuration
|
||||||
|
template:
|
||||||
|
src: nginx.conf.j2
|
||||||
|
dest: /etc/nginx/nginx.conf
|
||||||
|
mode: '0644'
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Ensure Nginx is enabled and started
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
enabled: yes
|
||||||
|
state: started
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
27
ansible/roles/nginx_proxy/templates/nginx.conf.j2
Normal file
27
ansible/roles/nginx_proxy/templates/nginx.conf.j2
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
types_hash_max_size 2048;
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
45
ansible/roles/nginx_proxy/templates/proxy.conf.j2
Normal file
45
ansible/roles/nginx_proxy/templates/proxy.conf.j2
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
upstream backend {
|
||||||
|
{% if siteA.site_ip %}
|
||||||
|
server {{ siteA.site_ip }} max_fails=1 fail_timeout=10s;
|
||||||
|
{% endif %}
|
||||||
|
{% if siteB.site_ip %}
|
||||||
|
server {{ siteB.site_ip }} max_fails=1 fail_timeout=10s;
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {{ proxy.proxy_domain }};
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name {{ proxy.proxy_domain }};
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/{{ ssl_cert_file }};
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/{{ ssl_key_file }};
|
||||||
|
|
||||||
|
error_page 502 503 504 /site_down.html;
|
||||||
|
|
||||||
|
location = /site_down.html {
|
||||||
|
root /var/www/errors;
|
||||||
|
internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://backend;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
|
||||||
|
proxy_intercept_errors on;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /health {
|
||||||
|
proxy_pass http://backend/health;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
}
|
35
ansible/roles/nginx_proxy/templates/site_down.html.j2
Normal file
35
ansible/roles/nginx_proxy/templates/site_down.html.j2
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Сайт не работает</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.message {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="message">
|
||||||
|
<h1>Сайт не работает</h1>
|
||||||
|
<p>Просьба обратиться в техподдержку или на сервере в данный момент техработы.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
3
ansible/roles/nginx_proxy/vars/main.yml
Normal file
3
ansible/roles/nginx_proxy/vars/main.yml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
upstream_servers:
|
||||||
|
- "{{ siteA.site_ip }}"
|
||||||
|
- "{{ siteB.site_ip }}"
|
4
ansible/roles/nginx_site/handlers/main.yml
Normal file
4
ansible/roles/nginx_site/handlers/main.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
- name: Restart Nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: restarted
|
86
ansible/roles/nginx_site/tasks/main.yml
Normal file
86
ansible/roles/nginx_site/tasks/main.yml
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
- name: Install Nginx
|
||||||
|
zypper:
|
||||||
|
name: nginx
|
||||||
|
state: present
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Deploy Main Nginx Configuration
|
||||||
|
template:
|
||||||
|
src: nginx.conf.j2
|
||||||
|
dest: /etc/nginx/nginx.conf
|
||||||
|
mode: '0644'
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Deploy SiteA Configuration
|
||||||
|
template:
|
||||||
|
src: siteA.conf.j2
|
||||||
|
dest: /etc/nginx/conf.d/siteA.conf
|
||||||
|
when: "'SiteA' in group_names"
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Deploy SiteB Configuration
|
||||||
|
template:
|
||||||
|
src: siteB.conf.j2
|
||||||
|
dest: /etc/nginx/conf.d/siteB.conf
|
||||||
|
when: "'SiteB' in group_names"
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Create web root for SiteA
|
||||||
|
file:
|
||||||
|
path: /var/www/siteA
|
||||||
|
state: directory
|
||||||
|
owner: nginx
|
||||||
|
group: nginx
|
||||||
|
mode: '0755'
|
||||||
|
when: "'SiteA' in group_names"
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Create web root for SiteB
|
||||||
|
file:
|
||||||
|
path: /var/www/siteB
|
||||||
|
state: directory
|
||||||
|
owner: nginx
|
||||||
|
group: nginx
|
||||||
|
mode: '0755'
|
||||||
|
when: "'SiteB' in group_names"
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Deploy SiteA HTML
|
||||||
|
template:
|
||||||
|
src: index.html.j2
|
||||||
|
dest: /var/www/siteA/index.html
|
||||||
|
vars:
|
||||||
|
site_title: "{{ siteA.site_title }}"
|
||||||
|
site_h1: "{{ siteA.site_h1 }}"
|
||||||
|
site_h2: "{{ siteA.site_h2 }}"
|
||||||
|
site_p: "{{ siteA.site_p }}"
|
||||||
|
when: "'SiteA' in group_names"
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Deploy SiteB HTML
|
||||||
|
template:
|
||||||
|
src: index.html.j2
|
||||||
|
dest: /var/www/siteB/index.html
|
||||||
|
vars:
|
||||||
|
site_title: "{{ siteB.site_title }}"
|
||||||
|
site_h1: "{{ siteB.site_h1 }}"
|
||||||
|
site_h2: "{{ siteB.site_h2 }}"
|
||||||
|
site_p: "{{ siteB.site_p }}"
|
||||||
|
when: "'SiteB' in group_names"
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
||||||
|
|
||||||
|
- name: Ensure Nginx is enabled and started
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
enabled: yes
|
||||||
|
state: started
|
||||||
|
notify:
|
||||||
|
- Restart Nginx
|
24
ansible/roles/nginx_site/templates/index.html.j2
Normal file
24
ansible/roles/nginx_site/templates/index.html.j2
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{{ site_title }}</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 50px;
|
||||||
|
}
|
||||||
|
h1 { color: #ff5722; }
|
||||||
|
h2 { color: #ff9800; }
|
||||||
|
p { font-size: 18px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>{{ site_h1 }}</h1>
|
||||||
|
<h2>{{ site_h2 }}</h2>
|
||||||
|
<p>{{ site_p }}</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
27
ansible/roles/nginx_site/templates/nginx.conf.j2
Normal file
27
ansible/roles/nginx_site/templates/nginx.conf.j2
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
tcp_nopush on;
|
||||||
|
tcp_nodelay on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
types_hash_max_size 2048;
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
16
ansible/roles/nginx_site/templates/siteA.conf.j2
Normal file
16
ansible/roles/nginx_site/templates/siteA.conf.j2
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {{ siteA.site_domain }};
|
||||||
|
|
||||||
|
root /var/www/siteA;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /health {
|
||||||
|
return 200 'SiteA is up';
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
}
|
16
ansible/roles/nginx_site/templates/siteB.conf.j2
Normal file
16
ansible/roles/nginx_site/templates/siteB.conf.j2
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {{ siteB.site_domain }};
|
||||||
|
|
||||||
|
root /var/www/siteB;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /health {
|
||||||
|
return 200 'SiteB is up';
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
}
|
0
ansible/roles/nginx_site/vars/main.yml
Normal file
0
ansible/roles/nginx_site/vars/main.yml
Normal file
38
ansible/roles/ssl_certificate/tasks/main.yml
Normal file
38
ansible/roles/ssl_certificate/tasks/main.yml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
- name: Install OpenSSL
|
||||||
|
ansible.builtin.zypper:
|
||||||
|
name: openssl
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create SSL directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ssl_cert_path }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Generate private key
|
||||||
|
community.crypto.openssl_privatekey:
|
||||||
|
path: "{{ ssl_cert_path }}/{{ ssl_key_file }}"
|
||||||
|
size: 2048
|
||||||
|
type: RSA
|
||||||
|
mode: '0600'
|
||||||
|
|
||||||
|
- name: Generate CSR (Certificate Signing Request)
|
||||||
|
community.crypto.openssl_csr:
|
||||||
|
path: "{{ ssl_cert_path }}/{{ ssl_csr_file }}"
|
||||||
|
privatekey_path: "{{ ssl_cert_path }}/{{ ssl_key_file }}"
|
||||||
|
common_name: "{{ ssl_common_name }}"
|
||||||
|
country_name: "{{ ssl_country }}"
|
||||||
|
state_or_province_name: "{{ ssl_state }}"
|
||||||
|
locality_name: "{{ ssl_locality }}"
|
||||||
|
organization_name: "{{ ssl_organization }}"
|
||||||
|
organizational_unit_name: "{{ ssl_organizational_unit }}"
|
||||||
|
|
||||||
|
- name: Generate Self-Signed SSL Certificate
|
||||||
|
community.crypto.x509_certificate:
|
||||||
|
path: "{{ ssl_cert_path }}/{{ ssl_cert_file }}"
|
||||||
|
privatekey_path: "{{ ssl_cert_path }}/{{ ssl_key_file }}"
|
||||||
|
csr_path: "{{ ssl_cert_path }}/{{ ssl_csr_file }}"
|
||||||
|
provider: selfsigned
|
||||||
|
force: yes
|
11
ansible/roles/ssl_certificate/vars/main.yml
Normal file
11
ansible/roles/ssl_certificate/vars/main.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
ssl_cert_path: "/etc/nginx/ssl"
|
||||||
|
ssl_cert_file: "proxy.crt"
|
||||||
|
ssl_key_file: "proxy.key"
|
||||||
|
ssl_csr_file: "proxy.csr"
|
||||||
|
|
||||||
|
ssl_common_name: "{{ proxy.proxy_domain }}"
|
||||||
|
ssl_country: "RU"
|
||||||
|
ssl_state: "Some-State"
|
||||||
|
ssl_locality: "Some-City"
|
||||||
|
ssl_organization: "Your Company"
|
||||||
|
ssl_organizational_unit: "IT"
|
20
ansible/roles/ssl_certificate_cmd/tasks/main.yml
Normal file
20
ansible/roles/ssl_certificate_cmd/tasks/main.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
- name: Install OpenSSL
|
||||||
|
zypper:
|
||||||
|
name: openssl
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create SSL directory
|
||||||
|
file:
|
||||||
|
path: "{{ ssl_cert_path }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Generate Self-Signed SSL Certificate
|
||||||
|
command: >
|
||||||
|
openssl req -x509 -nodes -days 365
|
||||||
|
-newkey rsa:2048
|
||||||
|
-keyout {{ ssl_cert_path }}/{{ ssl_key_file }}
|
||||||
|
-out {{ ssl_cert_path }}/{{ ssl_cert_file }}
|
||||||
|
-subj "{{ ssl_subject }}"
|
4
ansible/roles/ssl_certificate_cmd/vars/main.yml
Normal file
4
ansible/roles/ssl_certificate_cmd/vars/main.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
ssl_cert_path: "/etc/nginx/ssl"
|
||||||
|
ssl_cert_file: "proxy.crt"
|
||||||
|
ssl_key_file: "proxy.key"
|
||||||
|
ssl_subject: "/C=RU/ST=Some-State/L=Some-City/O=Your Company/CN={{ proxy.proxy_domain }}"
|
31
docker-compose.yml
Normal file
31
docker-compose.yml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
services:
|
||||||
|
nginx:
|
||||||
|
image: nginx:latest
|
||||||
|
container_name: nginx
|
||||||
|
volumes:
|
||||||
|
- ./nginx/conf.d:/etc/nginx/conf.d
|
||||||
|
- ./nginx/ssl:/etc/nginx/ssl
|
||||||
|
- ./nginx/html:/usr/share/nginx/html
|
||||||
|
- /coursework/nginx/ssl:/coursework/nginx/ssl
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
depends_on:
|
||||||
|
- gitea
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
gitea:
|
||||||
|
image: gitea/gitea:latest
|
||||||
|
container_name: gitea
|
||||||
|
environment:
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
volumes:
|
||||||
|
- ./gitea-data:/data
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
- "222:22"
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
gitea-data:
|
Loading…
Reference in New Issue
Block a user