diff --git a/ansible/Jenkinsfile b/ansible/Jenkinsfile index 69563bb..83b0713 100644 --- a/ansible/Jenkinsfile +++ b/ansible/Jenkinsfile @@ -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.' + } + } +} diff --git a/ansible/ansible/roles/firewall/tasks/main.yml b/ansible/ansible/roles/firewall/tasks/main.yml new file mode 100644 index 0000000..dffa1c6 --- /dev/null +++ b/ansible/ansible/roles/firewall/tasks/main.yml @@ -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 }}" \ No newline at end of file diff --git a/ansible/ansible/roles/firewall/vars/main.yml b/ansible/ansible/roles/firewall/vars/main.yml new file mode 100644 index 0000000..76e350f --- /dev/null +++ b/ansible/ansible/roles/firewall/vars/main.yml @@ -0,0 +1,4 @@ +firewall_ports: + - { port: 22, protocol: tcp } + - { port: 80, protocol: tcp } + - { port: 443, protocol: tcp } \ No newline at end of file diff --git a/ansible/ansible/roles/nginx_proxy/tasks/main.yml b/ansible/ansible/roles/nginx_proxy/tasks/main.yml new file mode 100644 index 0000000..ec44e69 --- /dev/null +++ b/ansible/ansible/roles/nginx_proxy/tasks/main.yml @@ -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 \ No newline at end of file diff --git a/ansible/ansible/roles/nginx_proxy/templates/proxy.conf.j2 b/ansible/ansible/roles/nginx_proxy/templates/proxy.conf.j2 new file mode 100644 index 0000000..d848f2c --- /dev/null +++ b/ansible/ansible/roles/nginx_proxy/templates/proxy.conf.j2 @@ -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; + } +} \ No newline at end of file diff --git a/ansible/ansible/roles/nginx_proxy/vars/main.yml b/ansible/ansible/roles/nginx_proxy/vars/main.yml new file mode 100644 index 0000000..c2f3274 --- /dev/null +++ b/ansible/ansible/roles/nginx_proxy/vars/main.yml @@ -0,0 +1,3 @@ +upstream_servers: + - "{{ siteA.site_ip }}" + - "{{ siteB.site_ip }}" diff --git a/ansible/ansible/roles/nginx_site/tasks/main.yml b/ansible/ansible/roles/nginx_site/tasks/main.yml new file mode 100644 index 0000000..ef9f480 --- /dev/null +++ b/ansible/ansible/roles/nginx_site/tasks/main.yml @@ -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 \ No newline at end of file diff --git a/ansible/ansible/roles/nginx_site/templates/index.html.j2 b/ansible/ansible/roles/nginx_site/templates/index.html.j2 new file mode 100644 index 0000000..2780503 --- /dev/null +++ b/ansible/ansible/roles/nginx_site/templates/index.html.j2 @@ -0,0 +1,24 @@ + + +
+ +{{ site_p }}
+ + \ No newline at end of file diff --git a/ansible/ansible/roles/nginx_site/templates/siteA.conf.j2 b/ansible/ansible/roles/nginx_site/templates/siteA.conf.j2 new file mode 100644 index 0000000..1f2140e --- /dev/null +++ b/ansible/ansible/roles/nginx_site/templates/siteA.conf.j2 @@ -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; + } +} diff --git a/ansible/ansible/roles/nginx_site/templates/siteB.conf.j2 b/ansible/ansible/roles/nginx_site/templates/siteB.conf.j2 new file mode 100644 index 0000000..d8913c5 --- /dev/null +++ b/ansible/ansible/roles/nginx_site/templates/siteB.conf.j2 @@ -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; + } +} diff --git a/ansible/ansible/roles/nginx_site/vars/main.yml b/ansible/ansible/roles/nginx_site/vars/main.yml new file mode 100644 index 0000000..27a52fb --- /dev/null +++ b/ansible/ansible/roles/nginx_site/vars/main.yml @@ -0,0 +1 @@ +additional_content: "{{ additional_content | default('') }}" \ No newline at end of file diff --git a/ansible/ansible/roles/ssl_certificate/tasks/main.yml b/ansible/ansible/roles/ssl_certificate/tasks/main.yml new file mode 100644 index 0000000..9f8fd05 --- /dev/null +++ b/ansible/ansible/roles/ssl_certificate/tasks/main.yml @@ -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 }}" \ No newline at end of file diff --git a/ansible/ansible/roles/ssl_certificate/vars/main.yml b/ansible/ansible/roles/ssl_certificate/vars/main.yml new file mode 100644 index 0000000..c7a9501 --- /dev/null +++ b/ansible/ansible/roles/ssl_certificate/vars/main.yml @@ -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 }}" \ No newline at end of file diff --git a/ansible/ansible/roles/vars/main.yml b/ansible/ansible/roles/vars/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml new file mode 100644 index 0000000..1489f3e --- /dev/null +++ b/ansible/group_vars/all.yml @@ -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" diff --git a/ansible/playbook.yml b/ansible/playbook.yml index 4f4f23c..5645d55 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -1,4 +1,15 @@ - hosts: all become: true roles: - - site_setup \ No newline at end of file + - firewall + +- hosts: SiteA,SiteB + become: true + roles: + - nginx_site + +- hosts: proxy + become: true + roles: + - ssl_certificate + - nginx_proxy \ No newline at end of file diff --git a/ansible/roles/site_setup/tasks/configure_firewall.yml b/ansible/roles/site_setup/tasks/configure_firewall.yml deleted file mode 100644 index 2cbb0a5..0000000 --- a/ansible/roles/site_setup/tasks/configure_firewall.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/ansible/roles/site_setup/tasks/configure_proxy.yml b/ansible/roles/site_setup/tasks/configure_proxy.yml deleted file mode 100644 index 3e349b3..0000000 --- a/ansible/roles/site_setup/tasks/configure_proxy.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/ansible/roles/site_setup/tasks/configure_site.yml b/ansible/roles/site_setup/tasks/configure_site.yml deleted file mode 100644 index 1d62aa2..0000000 --- a/ansible/roles/site_setup/tasks/configure_site.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/ansible/roles/site_setup/tasks/generate_ssl.yml b/ansible/roles/site_setup/tasks/generate_ssl.yml deleted file mode 100644 index fc96e72..0000000 --- a/ansible/roles/site_setup/tasks/generate_ssl.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/ansible/roles/site_setup/tasks/install.yml b/ansible/roles/site_setup/tasks/install.yml deleted file mode 100644 index f3d2079..0000000 --- a/ansible/roles/site_setup/tasks/install.yml +++ /dev/null @@ -1,7 +0,0 @@ -- name: Install Nginx - zypper: - name: nginx - state: present - force: yes - update_cache: yes - tags: install \ No newline at end of file diff --git a/ansible/roles/site_setup/tasks/main.yml b/ansible/roles/site_setup/tasks/main.yml deleted file mode 100644 index eb61aeb..0000000 --- a/ansible/roles/site_setup/tasks/main.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/ansible/roles/site_setup/templates/nginx_site.conf.j2 b/ansible/roles/site_setup/templates/nginx_site.conf.j2 deleted file mode 100644 index 26834d7..0000000 --- a/ansible/roles/site_setup/templates/nginx_site.conf.j2 +++ /dev/null @@ -1,9 +0,0 @@ -server { - listen 80; - server_name {{ site_name }}; - - location / { - root /var/www/{{ site_name }}; - index index.html; - } -} \ No newline at end of file diff --git a/ansible/roles/site_setup/templates/proxy.conf.j2 b/ansible/roles/site_setup/templates/proxy.conf.j2 deleted file mode 100644 index ae1d028..0000000 --- a/ansible/roles/site_setup/templates/proxy.conf.j2 +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/ansible/roles/site_setup/templates/site_index.html.j2 b/ansible/roles/site_setup/templates/site_index.html.j2 deleted file mode 100644 index 3afe96f..0000000 --- a/ansible/roles/site_setup/templates/site_index.html.j2 +++ /dev/null @@ -1,10 +0,0 @@ - - - -{{ additional_content }}
- - \ No newline at end of file diff --git a/ansible/roles/site_setup/vars/main.yml b/ansible/roles/site_setup/vars/main.yml deleted file mode 100644 index f8b1677..0000000 --- a/ansible/roles/site_setup/vars/main.yml +++ /dev/null @@ -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 }}" \ No newline at end of file