diff --git a/playbooks/prod_web.yml b/playbooks/prod_web.yml index 0a24d27..00d9044 100755 --- a/playbooks/prod_web.yml +++ b/playbooks/prod_web.yml @@ -12,94 +12,6 @@ - name: ensure docker network docker_network: name=web tags: [ docker ] - - name: ensure docker nginx config - copy: - dest: /data/nginx-certbot/user_conf.d/vhosts.conf - mode: "0750" - content: | - server { - listen 443 ssl default_server; - server_name desu.ltd; - ssl_certificate /etc/letsencrypt/live/desu.ltd/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/desu.ltd/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/desu.ltd/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://desultd:80; - } - } - server { - listen 443 ssl; - server_name www.9iron.club; - ssl_certificate /etc/letsencrypt/live/desu.ltd/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/desu.ltd/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/desu.ltd/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - return 301 $scheme://9iron.club$request_uri; - } - server { - listen 443 ssl; - server_name 9iron.club; - ssl_certificate /etc/letsencrypt/live/desu.ltd/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/desu.ltd/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/desu.ltd/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://9iron:80; - } - } - server { - listen 443 ssl; - server_name git.desu.ltd; - ssl_certificate /etc/letsencrypt/live/desu.ltd/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/desu.ltd/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/desu.ltd/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://gitea:3000; - } - } - server { - listen 443 ssl; - server_name nc.desu.ltd; - ssl_certificate /etc/letsencrypt/live/desu.ltd/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/desu.ltd/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/desu.ltd/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - add_header Strict-Transport-Security "max-age=31536000"; - client_max_body_size 0; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://nextcloud:80; - } - location ^~ /.well-known { - location = /.well-known/carddav { return 301 /remote.php/dav/; } - location = /.well-known/caldav { return 301 /remote.php/dav/; } - location ^~ /.well-known { return 301 /index.php$uri; } - try_files $uri $uri/ =404; - } - } - server { - listen 443 ssl; - server_name srv.9iron.club; - ssl_certificate /etc/letsencrypt/live/desu.ltd/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/desu.ltd/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/desu.ltd/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://srv:80; - } - } - tags: [ docker, ingress ] - name: include tasks for apps include_tasks: tasks/app/{{ task }} with_items: @@ -116,7 +28,6 @@ - gitea.yml - nextcloud.yml - srv.yml - - ingress-generic.yml loop_control: loop_var: task tags: [ always ] @@ -139,6 +50,45 @@ - repo: https://git.desu.ltd/salt/gitea-custom dest: /data/gitea/data/gitea/custom tags: [ web, git ] + - role: ingress + vars: + ingress_servers: + # desu.ltd + - name: desu.ltd + proxies: + - location: / + pass: http://desultd:80 + - name: git.desu.ltd + proxies: + - location: / + pass: http://gitea:3000 + - name: nc.desu.ltd + directives: + - "add_header Strict-Transport-Security \"max-age=31536000\"" + - "client_max_body_size 0" + proxies: + - location: / + pass: http://nextcloud:80 + locations: + - location: "^~ /.well-known" + contents: | + location = /.well-known/carddav { return 301 /remote.php/dav/; } + location = /.well-known/caldav { return 301 /remote.php/dav/; } + location ^~ /.well-known { return 301 /index.php$uri; } + try_files $uri $uri/ =404; + # 9iron + - name: www.9iron.club + directives: + - "return 301 $scheme://9iron.club$request_uri" + - name: 9iron.club + proxies: + - location: / + pass: http://9iron:80 + - name: srv.9iron.club + proxies: + - location: / + pass: http://srv:80 + tags: [ web, docker, ingress ] - hosts: web2.desu.ltd module_defaults: docker_container: @@ -149,38 +99,6 @@ - name: ensure docker network docker_network: name=web tags: [ docker ] - - name: ensure docker nginx config - copy: - dest: /data/nginx-certbot/user_conf.d/vhosts.conf - mode: "0750" - content: | - server { - listen 443 ssl default_server; - server_name cowfee.moe; - ssl_certificate /etc/letsencrypt/live/cowfee.moe/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/cowfee.moe/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/cowfee.moe/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://pleroma:4000; - } - } - server { - listen 443 ssl; - server_name tube.cowfee.moe; - ssl_certificate /etc/letsencrypt/live/cowfee.moe/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/cowfee.moe/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/cowfee.moe/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://peertube:9000; - } - } - tags: [ docker, ingress ] - name: include tasks for apps include_tasks: tasks/app/{{ task }} with_items: @@ -203,6 +121,18 @@ backup_s3backup_list_extra: - /data tags: [ backup ] + - role: ingress + vars: + ingress_servers: + - name: cowfee.moe + proxies: + - location: / + pass: http://pleroma:4000 + - name: tube.cowfee.moe + proxies: + - location: / + pass: http://peertube:9000 + tags: [ web, docker, ingress ] - hosts: web3.desu.ltd module_defaults: docker_container: @@ -213,51 +143,6 @@ - name: ensure docker network docker_network: name=web tags: [ docker ] - - name: ensure docker nginx config - copy: - dest: /data/nginx-certbot/user_conf.d/vhosts.conf - mode: "0750" - content: | - server { - listen 443 ssl default_server; - server_name netbox.desu.ltd; - ssl_certificate /etc/letsencrypt/live/netbox.desu.ltd/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/netbox.desu.ltd/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/netbox.desu.ltd/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://netbox:8080; - } - } - server { - listen 443 ssl; - server_name nagios.desu.ltd; - ssl_certificate /etc/letsencrypt/live/netbox.desu.ltd/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/netbox.desu.ltd/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/netbox.desu.ltd/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://nagios:80; - } - } - server { - listen 443 ssl; - server_name movie.desu.ltd; - ssl_certificate /etc/letsencrypt/live/netbox.desu.ltd/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/netbox.desu.ltd/privkey.pem; - ssl_trusted_certificate /etc/letsencrypt/live/netbox.desu.ltd/chain.pem; - ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; - location / { - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass http://movienight:8089; - } - } - tags: [ docker, ingress ] - name: include tasks for apps include_tasks: tasks/app/{{ task }} with_items: @@ -271,7 +156,6 @@ - movienight.yml - netbox.yml - nagios.yml - - ingress-generic.yml loop_control: loop_var: task tags: [ always ] @@ -281,3 +165,19 @@ backup_s3backup_list_extra: - /data tags: [ backup ] + - role: ingress + vars: + ingress_servers: + - name: netbox.desu.ltd + proxies: + - location: / + pass: http://netbox:8080 + - name: nagios.desu.ltd + proxies: + - location: / + pass: http://nagios:80 + - name: movie.desu.ltd + proxies: + - location: / + pass: http://movienight:8089 + tags: [ web, docker, ingress ] diff --git a/roles/ingress/defaults/main.yml b/roles/ingress/defaults/main.yml new file mode 100644 index 0000000..cbd65f1 --- /dev/null +++ b/roles/ingress/defaults/main.yml @@ -0,0 +1,39 @@ +#!/usr/bin/env ansible-playbook +# vim:ft=ansible: + +# Core container configuration +ingress_container_image: jonasal/nginx-certbot:latest +ingress_container_name: ingress + +# Secondary container configuration +ingress_container_http_port: "80" +ingress_container_https_port: "443" +ingress_container_persist_dir: "/data/nginx-certbot" +ingress_container_timezone: America/Chicago + +# Network configuration +ingress_container_networks: + - name: web + aliases: [ "ingress" ] + +# Certbot configuration +ingress_container_certbot_email: rehashedsalt@cock.li + +# Vhost configuration +# ingress_servers: +# - name: example.com +# proxies: +# - location: / +# pass: http://some-container:80 +# locations: +# - location: "^~ /.well-known" +# contents: | +# location = /.well-known/carddav { return 301 /remote.php/dav/; } +# location = /.well-known/caldav { return 301 /remote.php/dav/; } +# location ^~ /.well-known { return 301 /index.php$uri; } +# try_files $uri $uri/ =404; +# - name: redirect.example.com +# directives: +# # NOTE: Do NOT suffix with a semicolon; that gets added for you +# - "return 301 $scheme://example.com$request_uri" +ingress_servers: [] diff --git a/roles/ingress/handlers/main.yml b/roles/ingress/handlers/main.yml new file mode 100644 index 0000000..7bb364e --- /dev/null +++ b/roles/ingress/handlers/main.yml @@ -0,0 +1,5 @@ +#!/usr/bin/env ansible-playbook +# vim:ft=ansible: +- name: restart ingress container + docker_container: name="{{ ingress_container_name }}" state=started restart=yes + become: yes diff --git a/roles/ingress/tasks/main.yml b/roles/ingress/tasks/main.yml new file mode 100644 index 0000000..d6457ec --- /dev/null +++ b/roles/ingress/tasks/main.yml @@ -0,0 +1,24 @@ +#!/usr/bin/env ansible-playbook +# vim:ft=ansible: +- name: assure ingress container persist directories + file: path="{{ ingress_container_persist_dir }}/{{ item }}" state=directory owner=root mode=0755 + with_items: + - letsencrypt + - user_conf.d +- name: template out ingress configuration file + template: src=vhosts.conf.j2 dest="{{ ingress_container_persist_dir }}/user_conf.d/vhosts.conf" mode="0640" + notify: restart ingress container +- name: assure ingress container + docker_container: + name: ingress + image: "{{ ingress_container_image }}" + env: + TZ: "{{ ingress_container_timezone }}" + CERTBOT_EMAIL: "{{ ingress_container_certbot_email }}" + networks: "{{ ingress_container_networks }}" + ports: + - "{{ ingress_container_https_port }}:443" + - "{{ ingress_container_http_port }}:80" + volumes: + - "{{ ingress_container_persist_dir }}/letsencrypt:/etc/letsencrypt" + - "{{ ingress_container_persist_dir }}/user_conf.d:/etc/nginx/user_conf.d:ro" diff --git a/roles/ingress/templates/vhosts.conf.j2 b/roles/ingress/templates/vhosts.conf.j2 new file mode 100644 index 0000000..754eeb1 --- /dev/null +++ b/roles/ingress/templates/vhosts.conf.j2 @@ -0,0 +1,44 @@ +{% for server in ingress_servers %} +server { +{% if loop.index == 1 %} + listen {{ ingress_listen_args }} default_server; +{% else %} + listen {{ ingress_listen_args }} ssl; +{% endif %} + server_name {{ server.name }}; + + # TLS configuration + ssl_certificate /etc/letsencrypt/live/{{ ingress_servers[0].name }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ ingress_servers[0].name }}/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/{{ ingress_servers[0].name }}/chain.pem; + ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem; + +{% if server.directives is defined %} + # Extra directives +{% for directive in server.directives %} + {{ directive }}; +{% endfor %} +{% endif %} + +{% if server.proxies is defined %} + # Proxy locations +{% for proxy in server.proxies %} + location {{ proxy.location }} { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass {{ proxy.pass }}; + } +{% endfor %} +{% endif %} + +{% if server.locations is defined %} + # Extra manually-defined locations +{% for location in server.locations %} + location {{ location.location }} { + {{ location.contents }} + } +{% endfor %} +{% endif %} + +} +{% endfor %}