This commit is contained in:
reqwizz 2024-11-12 23:14:17 +03:00
parent df19e70c88
commit f803c5c74b
26 changed files with 332 additions and 241 deletions

160
ansible/Jenkinsfile vendored
View File

@ -1,80 +1,80 @@
pipeline {
agent any
environment {
ANSIBLE_HOST_KEY_CHECKING = 'false'
VAULT_PASSWORD = credentials('vault_password')
}
parameters {
choice(name: 'SITE_OPTION', choices: ['SiteA', 'SiteB', 'SiteA&B'], description: 'Select which site to deploy')
string(name: 'ADDITIONAL_CONTENT', defaultValue: 'Новое сообщение', description: 'Additional content to be included in the site')
}
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 sanitized_content = params.ADDITIONAL_CONTENT.replaceAll("'", "\\'").replaceAll('"', '\\"')
def siteOption = params.SITE_OPTION
def targetGroups = ''
if (siteOption == 'SiteA') {
targetGroups = 'SiteA,proxy'
} else if (siteOption == 'SiteB') {
targetGroups = 'SiteB,proxy'
} else if (siteOption == 'SiteA&B') {
targetGroups = 'SiteA,SiteB,proxy'
}
ansiblePlaybook(
playbook: 'ansible/playbook.yml',
inventory: "ansible/inventory.yml",
extraVars: [
additional_content: sanitized_content,
ansible_ssh_private_key_file: env.DECYPTED_KEY_FILE
],
limit: targetGroups
)
}
}
}
}
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.'
}
}
}
pipeline {
agent any
environment {
ANSIBLE_HOST_KEY_CHECKING = 'false'
VAULT_PASSWORD = credentials('vault_password')
}
parameters {
choice(name: 'SITE_OPTION', choices: ['SiteA', 'SiteB', 'SiteA&B'], description: 'Select which site to deploy')
string(name: 'ADDITIONAL_CONTENT', defaultValue: 'Новое сообщение', description: 'Additional content to be included in the site')
}
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 sanitized_content = params.ADDITIONAL_CONTENT.replaceAll("'", "\\'").replaceAll('"', '\\"')
def siteOption = params.SITE_OPTION
def targetGroups = ''
if (siteOption == 'SiteA') {
targetGroups = 'SiteA,proxy'
} else if (siteOption == 'SiteB') {
targetGroups = 'SiteB,proxy'
} else if (siteOption == 'SiteA&B') {
targetGroups = 'SiteA,SiteB,proxy'
}
ansiblePlaybook(
playbook: 'ansible/playbook.yml',
inventory: "ansible/inventory.yml",
extraVars: [
additional_content: sanitized_content,
ansible_ssh_private_key_file: env.DECYPTED_KEY_FILE
],
limit: targetGroups
)
}
}
}
}
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.'
}
}
}

View File

@ -0,0 +1,18 @@
- name: Install firewalld
zypper:
name: firewalld
state: present
- name: Ensure firewalld is enabled and started
systemd:
name: firewalld
enabled: yes
state: started
- name: Open specified firewall ports
firewalld:
port: "{{ item.port }}/{{ item.protocol }}"
permanent: yes
state: enabled
immediate: yes
loop: "{{ firewall_ports }}"

View File

@ -0,0 +1,4 @@
firewall_ports:
- { port: 22, protocol: tcp }
- { port: 80, protocol: tcp }
- { port: 443, protocol: tcp }

View File

@ -0,0 +1,20 @@
- name: Install Nginx
zypper:
name: nginx
state: present
- name: Ensure Nginx is enabled and started
systemd:
name: nginx
enabled: yes
state: started
- name: Deploy Proxy Configuration
template:
src: proxy.conf.j2
dest: /etc/nginx/conf.d/proxy.conf
- name: Reload Nginx
systemd:
name: nginx
state: reloaded

View File

@ -0,0 +1,26 @@
upstream backend {
{% for server in upstream_servers %}
server {{ server }} max_fails=3 fail_timeout=30s;
{% endfor %}
}
server {
listen 80;
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 }};
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;
}
location /health {
return 200 'Proxy is up';
add_header Content-Type text/plain;
}
}

View File

@ -0,0 +1,3 @@
upstream_servers:
- "{{ siteA.site_ip }}"
- "{{ siteB.site_ip }}"

View File

@ -0,0 +1,67 @@
- name: Install Nginx
zypper:
name: nginx
state: present
- name: Ensure Nginx is enabled and started
systemd:
name: nginx
enabled: yes
state: started
- name: Create web root for SiteA
file:
path: /var/www/siteA
state: directory
owner: nginx
group: nginx
mode: '0755'
when: inventory_hostname in groups['SiteA']
- name: Create web root for SiteB
file:
path: /var/www/siteB
state: directory
owner: nginx
group: nginx
mode: '0755'
when: inventory_hostname in groups['SiteB']
- name: Deploy SiteA Configuration
template:
src: siteA.conf.j2
dest: /etc/nginx/conf.d/siteA.conf
when: inventory_hostname in groups['SiteA']
- name: Deploy SiteB Configuration
template:
src: siteB.conf.j2
dest: /etc/nginx/conf.d/siteB.conf
when: inventory_hostname in groups['SiteB']
- 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: inventory_hostname in groups['SiteA']
- 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: inventory_hostname in groups['SiteB']
- name: Reload Nginx
systemd:
name: nginx
state: reloaded

View 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>

View 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;
}
}

View 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;
}
}

View File

@ -0,0 +1 @@
additional_content: "{{ additional_content | default('') }}"

View File

@ -0,0 +1,22 @@
- 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 }}"
args:
creates: "{{ ssl_cert_path }}/{{ ssl_cert_file }}"

View 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 }}"

View File

View File

@ -0,0 +1,19 @@
siteA:
site_title: "SiteA - Добро пожаловать"
site_h1: "Добро пожаловать на SiteA"
site_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: "Секция 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"

View File

@ -1,4 +1,15 @@
- hosts: all
become: true
roles:
- site_setup
- firewall
- hosts: SiteA,SiteB
become: true
roles:
- nginx_site
- hosts: proxy
become: true
roles:
- ssl_certificate
- nginx_proxy

View File

@ -1,28 +0,0 @@
- name: Start and enable firewalld
service:
name: firewalld
state: started
enabled: true
tags: firewall
- name: Open port 80 for HTTP
ansible.builtin.firewalld:
port: 80/tcp
permanent: true
state: enabled
immediate: yes
tags: firewall
- name: Open port 443 for HTTPS
ansible.builtin.firewalld:
port: 443/tcp
permanent: true
state: enabled
immediate: yes
tags: firewall
- name: Reload firewalld to apply changes
ansible.builtin.service:
name: firewalld
state: reloaded
tags: firewall

View File

@ -1,11 +0,0 @@
- name: Configure Nginx as HTTPS proxy
template:
src: proxy.conf.j2
dest: /etc/nginx/conf.d/proxy.conf
tags: proxy
- name: Restart Nginx
service:
name: nginx
state: restarted
tags: proxy

View File

@ -1,24 +0,0 @@
- name: Create site directories
file:
path: "/var/www/{{ site_name }}"
state: directory
mode: '0755'
tags: configure_site
- name: Deploy site content
template:
src: site_index.html.j2
dest: "/var/www/{{ site_name }}/index.html"
tags: configure_site
- name: Configure Nginx for {{ site_name }}
template:
src: nginx_site.conf.j2
dest: "/etc/nginx/conf.d/{{ site_name }}.conf"
tags: configure_site
- name: Restart Nginx
service:
name: nginx
state: restarted
tags: configure_site

View File

@ -1,26 +0,0 @@
- name: Ensure SSL directory exists
file:
path: /etc/nginx/ssl
state: directory
mode: '0700'
tags: ssl
- name: Generate private key
openssl_privatekey:
path: /etc/nginx/ssl/{{ proxy_name }}.key
size: 2048
type: RSA
mode: '0600'
owner: root
group: root
tags: ssl
- name: Generate self-signed SSL certificate
openssl_certificate:
path: /etc/nginx/ssl/{{ proxy_name }}.crt
privatekey_path: /etc/nginx/ssl/{{ proxy_name }}.key
owner: root
group: root
mode: '0600'
provider: selfsigned
tags: ssl

View File

@ -1,7 +0,0 @@
- name: Install Nginx
zypper:
name: nginx
state: present
force: yes
update_cache: yes
tags: install

View File

@ -1,14 +0,0 @@
- import_tasks: install.yml
tags: install
- import_tasks: configure_site.yml
tags: configure_site
- import_tasks: configure_firewall.yml
tags: firewall
- import_tasks: generate_ssl.yml
tags: ssl
- import_tasks: configure_proxy.yml
tags: proxy

View File

@ -1,9 +0,0 @@
server {
listen 80;
server_name {{ site_name }};
location / {
root /var/www/{{ site_name }};
index index.html;
}
}

View File

@ -1,26 +0,0 @@
upstream backend_servers {
server {{ backend_ip_1 }}:80;
server {{ backend_ip_2 }}:80;
}
server {
listen 80;
server_name {{ proxy_name }};
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name {{ proxy_name }};
ssl_certificate /etc/nginx/ssl/{{ proxy_name }}.crt;
ssl_certificate_key /etc/nginx/ssl/{{ proxy_name }}.key;
location / {
proxy_pass http://backend_servers;
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_set_header X-Forwarded-Proto $scheme;
}
}

View File

@ -1,10 +0,0 @@
<html>
<head>
<meta charset="UTF-8">
<title>{{ site_name }}</title>
</head>
<body>
<h1>{{ site_name }}</h1>
<p>{{ additional_content }}</p>
</body>
</html>

View File

@ -1,5 +0,0 @@
site_name: "example_site"
proxy_name: "proxy_server"
backend_ip_1: "192.168.0.61"
backend_ip_2: "192.168.0.62"
additional_content: "Welcome to {{ site_name }}"