From 368eeeaa0bf94c2d8a8bcb2a35fa9cfef8002ccc Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sun, 25 Nov 2018 15:05:11 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B0?= =?UTF-8?q?=20=D1=80=D0=BE=D0=BB=D0=B5=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- README.md | 11 ++++ ansible/amber.yml | 55 ++++++++++++------- .../blocks/nginx-proxy/defaults/main.yml | 5 ++ .../roles/blocks/nginx-proxy/tasks/main.yml | 19 +++++++ .../blocks/nginx-proxy/templates/site.conf.j2 | 15 +++++ ansible/roles/blocks/owner/tasks/main.yml | 10 ++-- .../owner/templates/{envs.j2 => env.j2} | 0 ansible/roles/docker-app/meta/main.yml | 7 +-- ansible/roles/docker-app/tasks/main.yml | 8 +++ .../roles/nginx-web-proxy/defaults/main.yml | 9 +++ ansible/roles/nginx-web-proxy/tasks/main.yml | 20 +++++++ ansible/templates/vakhrushev.me.conf.j2 | 33 +++++++++++ ansible/vars/apps.yml | 19 ++++++- 14 files changed, 180 insertions(+), 33 deletions(-) create mode 100644 ansible/roles/blocks/nginx-proxy/defaults/main.yml create mode 100644 ansible/roles/blocks/nginx-proxy/tasks/main.yml create mode 100755 ansible/roles/blocks/nginx-proxy/templates/site.conf.j2 rename ansible/roles/blocks/owner/templates/{envs.j2 => env.j2} (100%) create mode 100644 ansible/roles/nginx-web-proxy/defaults/main.yml create mode 100644 ansible/roles/nginx-web-proxy/tasks/main.yml create mode 100755 ansible/templates/vakhrushev.me.conf.j2 diff --git a/Makefile b/Makefile index a41b45f..cc2a2cf 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ install-roles: ansible-galaxy install -r "ansible/requirements.yml" -test-rebuild: +rebuild-test-machine: vagrant destroy -f && vagrant up configure: diff --git a/README.md b/README.md index 6038aab..2bd5314 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,14 @@ * Написать плейбук для предварительной настройки сервера, создания пользователя для входа, пользователя для деплоя, отключения ssh-логина для root. + +## Структура сервера приложений + +Структура состоит из двух слоев: + +- Frontend. Набор конфигов Nginx, которые отвечают за передачу запросов к приложению. + По большей части эти конфиги содержат в себе описания прокси и настройки сертификатов. + +- Backend. Набор приложений. Каждое приложение представляет собой набор docker-контейнеров, + определяется пользователем, конфигурацией в переменных окружения, конфигурацией cron-задач + и другими настройками. Приложения изолированы друг от друга. diff --git a/ansible/amber.yml b/ansible/amber.yml index 0e2b9d6..9b19c7f 100644 --- a/ansible/amber.yml +++ b/ansible/amber.yml @@ -9,27 +9,27 @@ tasks: -# - include_role: -# name: yatesr.timezone -# vars: -# timezone: UTC -# -# - include_role: -# name: geerlingguy.security -# vars: -# security_ssh_permit_root_login: "yes" -# security_autoupdate_enabled: false -# security_fail2ban_enabled: false -# -# - include_role: -# name: geerlingguy.nginx -# vars: -# nginx_remove_default_vhost: true -# -# - include_role: -# name: geerlingguy.docker -# vars: -# docker_users: '{{ apps | map(attribute="username") | list }}' + - include_role: + name: yatesr.timezone + vars: + timezone: UTC + + - include_role: + name: geerlingguy.security + vars: + security_ssh_permit_root_login: "yes" + security_autoupdate_enabled: false + security_fail2ban_enabled: false + + - include_role: + name: geerlingguy.nginx + vars: + nginx_remove_default_vhost: true + + - include_role: + name: geerlingguy.docker + vars: + docker_users: '{{ apps | map(attribute="username") | list }}' - include_role: name: docker-app @@ -42,3 +42,16 @@ loop_control: loop_var: app_item + - include_role: + name: nginx-web-proxy + private: yes + vars: + nginx_proxy_name: '{{ fr_item.name }}' + nginx_proxy_template: '{{ fr_item.template }}' + nginx_proxy_params: '{{ fr_item.params | default({}) }}' + nginx_ssl_type: '{{ fr_item.ssl_type }}' + nginx_ssl_email: '{{ fr_item.ssl_email }}' + nginx_ssl_domains: '{{ fr_item.ssl_domains }}' + with_items: '{{ frontends }}' + loop_control: + loop_var: fr_item diff --git a/ansible/roles/blocks/nginx-proxy/defaults/main.yml b/ansible/roles/blocks/nginx-proxy/defaults/main.yml new file mode 100644 index 0000000..c009a4a --- /dev/null +++ b/ansible/roles/blocks/nginx-proxy/defaults/main.yml @@ -0,0 +1,5 @@ +--- +nginx_proxy_name: '' +nginx_proxy_dir: '/var/www/{{ nginx_proxy_name }}' +nginx_proxy_web_root: '{{ nginx_proxy_dir }}/current' +nginx_proxy_template: site.conf.j2 diff --git a/ansible/roles/blocks/nginx-proxy/tasks/main.yml b/ansible/roles/blocks/nginx-proxy/tasks/main.yml new file mode 100644 index 0000000..6c59b84 --- /dev/null +++ b/ansible/roles/blocks/nginx-proxy/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: "Create nginx config for {{ nginx_proxy_name }} from {{ nginx_proxy_template }}." + template: + src: '{{ nginx_proxy_template }}' + dest: "/etc/nginx/sites-enabled/{{ nginx_proxy_name }}.conf" + notify: restart nginx + tags: + - webserver + +- name: "Create root folder for {{ nginx_proxy_name }}." + file: + path: "{{ nginx_proxy_dir }}" + state: directory + owner: "{{ deploy_user }}" + group: www-data + recurse: yes + notify: restart nginx + tags: + - webserver diff --git a/ansible/roles/blocks/nginx-proxy/templates/site.conf.j2 b/ansible/roles/blocks/nginx-proxy/templates/site.conf.j2 new file mode 100755 index 0000000..20e60bf --- /dev/null +++ b/ansible/roles/blocks/nginx-proxy/templates/site.conf.j2 @@ -0,0 +1,15 @@ +server { + server_name www.{{ nginx_proxy_domain }}; + return 301 $scheme://{{ nginx_proxy_domain }}$request_uri; +} + +server { + listen 80; + server_name {{ nginx_proxy_domain }}; + + location / { + root {{ nginx_proxy_web_root }}; + index index.html; + try_files $uri $uri/ =404; + } +} diff --git a/ansible/roles/blocks/owner/tasks/main.yml b/ansible/roles/blocks/owner/tasks/main.yml index 465df83..0eb2cd3 100644 --- a/ansible/roles/blocks/owner/tasks/main.yml +++ b/ansible/roles/blocks/owner/tasks/main.yml @@ -25,8 +25,10 @@ - name: 'Set up environment variables for user "{{ owner_name }}".' template: - src: envs.j2 - dest: '/home/{{ owner_name }}/.envs' + src: env.j2 + dest: '/home/{{ owner_name }}/.env' + owner: '{{ owner_name }}' + group: '{{ owner_group }}' - name: 'Remove absent environment variables for user "{{ owner_name }}" from bashrc.' lineinfile: @@ -38,5 +40,5 @@ - name: 'Include environment variables for user "{{ owner_name }}" in bashrc.' lineinfile: path: '/home/{{ owner_name }}/.bashrc' - regexp: '^\. ~\/\.envs' - line: '. ~/.envs' + regexp: '^\. ~\/\.env' + line: '. ~/.env' diff --git a/ansible/roles/blocks/owner/templates/envs.j2 b/ansible/roles/blocks/owner/templates/env.j2 similarity index 100% rename from ansible/roles/blocks/owner/templates/envs.j2 rename to ansible/roles/blocks/owner/templates/env.j2 diff --git a/ansible/roles/docker-app/meta/main.yml b/ansible/roles/docker-app/meta/main.yml index 7b01c20..cd21505 100644 --- a/ansible/roles/docker-app/meta/main.yml +++ b/ansible/roles/docker-app/meta/main.yml @@ -1,7 +1,2 @@ --- -dependencies: - - role: blocks/owner - owner_name: '{{ username }}' - owner_group: '{{ username }}' - owner_ssh_keys: '{{ ssh_keys | default([]) }}' - owner_envs: '{{ env | default({}) }}' + diff --git a/ansible/roles/docker-app/tasks/main.yml b/ansible/roles/docker-app/tasks/main.yml index ed97d53..d454b76 100644 --- a/ansible/roles/docker-app/tasks/main.yml +++ b/ansible/roles/docker-app/tasks/main.yml @@ -1 +1,9 @@ --- +- name: Create owner. + include_role: + name: blocks/owner + vars: + owner_name: '{{ username }}' + owner_group: '{{ username }}' + owner_ssh_keys: '{{ ssh_keys | default([]) }}' + owner_envs: '{{ env | default({}) }}' diff --git a/ansible/roles/nginx-web-proxy/defaults/main.yml b/ansible/roles/nginx-web-proxy/defaults/main.yml new file mode 100644 index 0000000..5386655 --- /dev/null +++ b/ansible/roles/nginx-web-proxy/defaults/main.yml @@ -0,0 +1,9 @@ +--- +nginx_proxy_name: '' +nginx_proxy_template: '' +nginx_proxy_params: {} + +nginx_ssl_type: ~ +nginx_ssl_name: '{{ nginx_proxy_name }}' +nginx_ssl_email: '' +nginx_ssl_domains: [] diff --git a/ansible/roles/nginx-web-proxy/tasks/main.yml b/ansible/roles/nginx-web-proxy/tasks/main.yml new file mode 100644 index 0000000..c28b07f --- /dev/null +++ b/ansible/roles/nginx-web-proxy/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: "Configure ssl certificate for {{ nginx_proxy_name }}" + include_role: + name: blocks/ssl-certificate + vars: + cert_type: '{{ nginx_ssl_type }}' + cert_name: '{{ nginx_ssl_name }}' + cert_email: '{{ nginx_ssl_email }}' + cert_domains: '{{ nginx_ssl_domains }}' + when: nginx_ssl_type is not none + tags: + - webserver + +- name: "Create nginx config for {{ nginx_proxy_name }} from {{ nginx_proxy_template }}." + template: + src: '{{ nginx_proxy_template }}' + dest: "/etc/nginx/sites-enabled/{{ nginx_proxy_name }}.conf" + notify: restart nginx + tags: + - webserver diff --git a/ansible/templates/vakhrushev.me.conf.j2 b/ansible/templates/vakhrushev.me.conf.j2 new file mode 100755 index 0000000..07f6f5d --- /dev/null +++ b/ansible/templates/vakhrushev.me.conf.j2 @@ -0,0 +1,33 @@ +server { + server_name www.vakhrushev.me; + return 301 $scheme://vakhrushev.me$request_uri; +} + +server { + listen 443 ssl http2; + server_name vakhrushev.me; + + ssl on; + ssl_certificate {{ vars[nginx_ssl_name + "_ssl_certificate"] }}; + ssl_certificate_key {{ vars[nginx_ssl_name + "_ssl_key"] }}; + ssl_trusted_certificate {{ vars[nginx_ssl_name + "_ssl_certificate"] }}; + + ssl_session_cache shared:SSL:50m; + ssl_session_timeout 5m; + ssl_stapling on; + ssl_stapling_verify on; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; + + ssl_dhparam {{ vars[nginx_ssl_name + "_ssl_dhparam"] }}; + ssl_prefer_server_ciphers on; + + location / { + proxy_pass http://localhost:{{ nginx_proxy_params.port }}; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + } +} diff --git a/ansible/vars/apps.yml b/ansible/vars/apps.yml index 1aada64..d5ebaab 100644 --- a/ansible/vars/apps.yml +++ b/ansible/vars/apps.yml @@ -1,8 +1,25 @@ --- + +# Приложения +# Описывают конфигурации приложений, секретные данные + apps: - name: homepage username: homepage ssh_keys: - '{{ lookup("file", "av_id_rsa.pub") }}' - domains: + + +# Конфигурации nginx +# Описывают конфиги nginx, сертификаты + +frontends: + - name: vakhrushev_me + template: vakhrushev.me.conf.j2 + params: + port: 16002 + ssl_type: self-signed + ssl_email: anwinged@ya.ru + ssl_domains: - vakhrushev.me + - www.vakhrushev.me