nginx role for deploying nginx and ssl
This commit is contained in:
commit
1aa985256f
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
__pycache__
|
20
LICENSE
Normal file
20
LICENSE
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2024 Shane Wadleigh
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
62
README.md
Normal file
62
README.md
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# ansible-roles-nginx
|
||||||
|
|
||||||
|
This role is designed to provide a reverse proxy in conjuction with another role based deployment such as a metrics stack
|
||||||
|
|
||||||
|
- https://nginx.org/
|
||||||
|
|
||||||
|
|
||||||
|
## Task Configuration
|
||||||
|
|
||||||
|
```
|
||||||
|
- name: Setup nginx
|
||||||
|
hosts: somehost
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- role: nginx
|
||||||
|
nginx_sites:
|
||||||
|
- name: lmer2-frontend
|
||||||
|
url: lmer2.20c.com
|
||||||
|
upstream: http://localhost:8001
|
||||||
|
ssl: false
|
||||||
|
- role: firewalld
|
||||||
|
firewalld_services:
|
||||||
|
- http
|
||||||
|
- https
|
||||||
|
firewalld_ports:
|
||||||
|
- 8100/tcp # dashboard insecure mode
|
||||||
|
firewalld_forwards:
|
||||||
|
- port: 80
|
||||||
|
to: 8080
|
||||||
|
- port: 443
|
||||||
|
to: 8443
|
||||||
|
```
|
||||||
|
|
||||||
|
`ssl` can have a few different meaningful values
|
||||||
|
- undfefined will skip ssl entirely including its inclusion in the templates
|
||||||
|
- true, lets encrypt will request a cert
|
||||||
|
- false, lets encrypt will not request a cert but the template will assume a cert exists
|
||||||
|
|
||||||
|
`ssl_barrow` can be set to the url of an existing cert to piggy back on another existing cert
|
||||||
|
|
||||||
|
|
||||||
|
## Deployment and Removal
|
||||||
|
|
||||||
|
|
||||||
|
Sometimes you need to manually stop the running containers to get a clean run when re-deploying
|
||||||
|
Services must be stopped as the respecitve user or another means to aquire the correct user scope for systemd
|
||||||
|
|
||||||
|
```
|
||||||
|
systemctl --user stop container-nginx.service
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook -i hosts site.yml --tags=firewalld,nginx --limit=somehost
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook -i hosts site.yml --tags=firewalld,nginx --extra-vars "container_state=absent firewall_action=remove" --limit=somehost
|
||||||
|
```
|
17
defaults/main.yml
Normal file
17
defaults/main.yml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
nginx_packages_intall: true
|
||||||
|
nginx_packages:
|
||||||
|
- nginx
|
||||||
|
- certbot
|
||||||
|
- python3-certbot-nginx
|
||||||
|
|
||||||
|
nginx_path: /etc/nginx/conf.d
|
||||||
|
nginx_default_template: basic-proxy
|
||||||
|
|
||||||
|
nginx_proxy_connection_timeout: 10
|
||||||
|
nginx_proxy_read_timeout: 200
|
||||||
|
nginx_proxy_send_timeout: 200
|
||||||
|
|
||||||
|
nginx_ssl_path: /etc/letsencrypt/live
|
||||||
|
# define email for dyanmic certificates
|
||||||
|
# nginx_ssl_email:
|
8
handlers/main.yml
Normal file
8
handlers/main.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Start/Enable nginx
|
||||||
|
listen: "restart nginx"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: nginx
|
||||||
|
state: restarted
|
||||||
|
enabled: true
|
37
meta/main.yml
Normal file
37
meta/main.yml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
dependencies: []
|
||||||
|
|
||||||
|
galaxy_info:
|
||||||
|
role_name: nginx
|
||||||
|
author: srw
|
||||||
|
description: An Ansible role for configuring ngix
|
||||||
|
company: "NMD, LLC"
|
||||||
|
license: "license (BSD, MIT)"
|
||||||
|
min_ansible_version: "2.10"
|
||||||
|
platforms:
|
||||||
|
- name: Fedora
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
- name: Debian
|
||||||
|
versions:
|
||||||
|
- buster
|
||||||
|
- bullseye
|
||||||
|
- bookworm
|
||||||
|
- name: Ubuntu
|
||||||
|
versions:
|
||||||
|
- bionic
|
||||||
|
- focal
|
||||||
|
- jammy
|
||||||
|
- name: Alpine
|
||||||
|
version:
|
||||||
|
- all
|
||||||
|
- name: ArchLinux
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
galaxy_tags:
|
||||||
|
- server
|
||||||
|
- system
|
||||||
|
- http
|
||||||
|
- nginx
|
||||||
|
- web
|
||||||
|
- proxy
|
30
tasks/main.yml
Normal file
30
tasks/main.yml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
- name: Role for setting up a nginx reverse proxy
|
||||||
|
block:
|
||||||
|
|
||||||
|
- name: gather local facts
|
||||||
|
set_fact:
|
||||||
|
local_user: "{{ lookup('env', 'USER') }}"
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: nginx checking packages
|
||||||
|
ansible.builtin.include_tasks: packages.yml
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- nginx-packages
|
||||||
|
|
||||||
|
- name: nginx setup configs
|
||||||
|
ansible.builtin.include_tasks: nginx.yml
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- nginx-configs
|
||||||
|
|
||||||
|
- name: nginx setup ssl
|
||||||
|
ansible.builtin.include_tasks: ssl.yml
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- nginx-ssl
|
||||||
|
|
||||||
|
when:
|
||||||
|
- nginx_sites is defined
|
||||||
|
|
25
tasks/nginx.yml
Normal file
25
tasks/nginx.yml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
- name: Setup nginx configs
|
||||||
|
block:
|
||||||
|
|
||||||
|
- name: Set selinux http can connect
|
||||||
|
ansible.builtin.command: setsebool -P httpd_can_network_connect 1
|
||||||
|
when:
|
||||||
|
- ansible_os_family == "RedHat"
|
||||||
|
|
||||||
|
- name: Template nginx server name hash config
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/server-name-hash.conf.j2"
|
||||||
|
dest: "{{ nginx_path }}/server-name-hash.conf"
|
||||||
|
mode: 0644
|
||||||
|
notify: "restart nginx"
|
||||||
|
when:
|
||||||
|
- nginx_server_name_hash is number
|
||||||
|
|
||||||
|
- name: Template nginx configs
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "templates/{{ item.template | d(nginx_default_template) }}.conf.j2"
|
||||||
|
dest: "{{ nginx_path }}/{{ item.name }}.conf"
|
||||||
|
mode: 0644
|
||||||
|
loop: "{{ nginx_sites }}"
|
||||||
|
notify: "restart nginx"
|
11
tasks/packages.yml
Normal file
11
tasks/packages.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: Setup nginx packages
|
||||||
|
block:
|
||||||
|
|
||||||
|
- name: Install nginx packages
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
with_items: "{{ nginx_packages }}"
|
||||||
|
when:
|
||||||
|
- nginx_packages_intall
|
29
tasks/ssl.yml
Normal file
29
tasks/ssl.yml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
- name: Setup ssl certificates
|
||||||
|
block:
|
||||||
|
|
||||||
|
- name: Request ssl certificates
|
||||||
|
ansible.builtin.command: certbot --nginx --agree-tos -n -m "{{ nginx_ssl_email }}" -d "{{ site.url }}"
|
||||||
|
args:
|
||||||
|
creates:
|
||||||
|
- "{{ nginx_ssl_path }}/{{ site.url }}/cert.pem"
|
||||||
|
- "{{ nginx_ssl_path }}/{{ site.url }}/chain.pem"
|
||||||
|
- "{{ nginx_ssl_path }}/{{ site.url }}/fullchain.pem"
|
||||||
|
- "{{ nginx_ssl_path }}/{{ site.url }}/privkey.pem"
|
||||||
|
vars:
|
||||||
|
ssl: true
|
||||||
|
when:
|
||||||
|
- site.ssl is defined
|
||||||
|
- site.ssl
|
||||||
|
loop: "{{ nginx_sites }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: site
|
||||||
|
|
||||||
|
- name: Add cron job for ssl renewal
|
||||||
|
ansible.builtin.cron:
|
||||||
|
name: "Renew ssl certs"
|
||||||
|
minute: "{{ 59 | random }}"
|
||||||
|
hour: "*/12"
|
||||||
|
job: "/usr/bin/certbot renew --nginx --quiet"
|
||||||
|
when:
|
||||||
|
- ssl is defined
|
52
templates/basic-proxy.conf.j2
Normal file
52
templates/basic-proxy.conf.j2
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# template: basic-proxy generated via ansible by {{ local_user }} at {{ ansible_date_time.time }} {{ ansible_date_time.date }}
|
||||||
|
|
||||||
|
{% if item.ssl is defined %}
|
||||||
|
server {
|
||||||
|
if ($host = {{ item.url }}) {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen {% if item.listen is defined %}{{ item.listen }}:{% endif %}80;
|
||||||
|
server_name {{ item.url }};
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen {% if item.listen is defined %}{{ item.listen }}:{% endif %}{% if item.ssl is defined %}443 ssl http2{% else %}80{% endif %};
|
||||||
|
server_name {{ item.url }};
|
||||||
|
access_log /var/log/nginx/http-access-{{ item.name }}.log;
|
||||||
|
|
||||||
|
{% if item.ssl is defined %}
|
||||||
|
{% if item.ssl_barrow is defined %}
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ item.ssl_barrow }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ item.ssl_barrow }}/privkey.pem;
|
||||||
|
{% else %}
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ item.url }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ item.url }}/privkey.pem;
|
||||||
|
{% endif %}
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if item.configs is defined %}
|
||||||
|
{% for config in item.configs %}
|
||||||
|
{{ config }};
|
||||||
|
{% endfor -%}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass {{ item.upstream }};
|
||||||
|
proxy_pass_header Server;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Scheme $scheme;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-NginX-Proxy true;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_read_timeout {{ item.read_timeout | d(nginx_proxy_read_timeout) }};
|
||||||
|
proxy_send_timeout {{ item.send_timeout | d(nginx_proxy_send_timeout) }};
|
||||||
|
proxy_connect_timeout {{ item.connection_timeout | d(nginx_proxy_connection_timeout) }};
|
||||||
|
}
|
||||||
|
}
|
3
templates/server-name-hash.conf.j2
Normal file
3
templates/server-name-hash.conf.j2
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# template: server-name-hash generated via ansible by {{ local_user }} at {{ ansible_date_time.time }} {{ ansible_date_time.date }}
|
||||||
|
|
||||||
|
server_names_hash_bucket_size {{ nginx_server_name_hash }};
|
57
templates/websocket-proxy.conf.j2
Normal file
57
templates/websocket-proxy.conf.j2
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# template: websocket-proxy generated via ansible by {{ local_user }} on {{ ansible_date_time.time }} {{ ansible_date_time.date }}
|
||||||
|
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if item.ssl is defined %}
|
||||||
|
server {
|
||||||
|
if ($host = {{ item.url }}) {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen {% if item.listen is defined %}{{ item.listen }}:{% endif %}80;
|
||||||
|
server_name {{ item.url }};
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen {% if item.listen is defined %}{{ item.listen }}:{% endif %}{% if item.ssl is defined %}443 ssl http2{% else %}80{% endif %};
|
||||||
|
server_name {{ item.url }};
|
||||||
|
access_log /var/log/nginx/http-access-{{ item.name }}.log;
|
||||||
|
|
||||||
|
{% if item.ssl is defined %}
|
||||||
|
{% if item.ssl_barrow is defined %}
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ item.ssl_barrow }}/privkey.pem;
|
||||||
|
{% else %}
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ item.url }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ item.url }}/privkey.pem;
|
||||||
|
{% endif %}
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if item.configs is defined %}
|
||||||
|
{% for config in item.configs %}
|
||||||
|
{{ config }};
|
||||||
|
{% endfor -%}
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass {{ item.upstream }};
|
||||||
|
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;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-NginX-Proxy true;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
proxy_read_timeout {{ item.read_timeout | d(nginx_proxy_read_timeout) }};
|
||||||
|
proxy_send_timeout {{ item.send_timeout | d(nginx_proxy_send_timeout) }};
|
||||||
|
proxy_connect_timeout {{ item.connection_timeout | d(nginx_proxy_connection_timeout) }};
|
||||||
|
}
|
||||||
|
}
|
16
vars/Archlinux.yml
Normal file
16
vars/Archlinux.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
promtail_journal: /run/log/journal
|
||||||
|
|
||||||
|
podman_packages:
|
||||||
|
- podman
|
||||||
|
- cni-plugins
|
||||||
|
- fuse-overlayfs
|
||||||
|
- slirp4netns
|
||||||
|
|
||||||
|
docker_packages:
|
||||||
|
- docker
|
||||||
|
|
||||||
|
nginx_packages:
|
||||||
|
- nginx
|
||||||
|
- certbot
|
||||||
|
- certbot-nginx
|
15
vars/RedHat.yml
Normal file
15
vars/RedHat.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
promtail_journal: /run/log/journal
|
||||||
|
|
||||||
|
podman_packages:
|
||||||
|
- podman
|
||||||
|
- systemd-container
|
||||||
|
|
||||||
|
docker_packages:
|
||||||
|
- docker-ce
|
||||||
|
|
||||||
|
nginx_packages:
|
||||||
|
- nginx
|
||||||
|
- httpd-tools
|
||||||
|
- certbot
|
||||||
|
- python3-certbot-nginx
|
19
vars/Ubuntu.yml
Normal file
19
vars/Ubuntu.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
promtail_journal: /var/log/journal
|
||||||
|
|
||||||
|
podman_packages:
|
||||||
|
- podman
|
||||||
|
- systemd-container
|
||||||
|
- acl
|
||||||
|
|
||||||
|
docker_packages:
|
||||||
|
- docker-ce
|
||||||
|
- docker-ce-cli
|
||||||
|
- containerd.io
|
||||||
|
- docker-compose
|
||||||
|
- sysdocker-compose-plugin
|
||||||
|
|
||||||
|
nginx_packages:
|
||||||
|
- nginx
|
||||||
|
- certbot
|
||||||
|
- python3-certbot-nginx
|
Loading…
Reference in New Issue
Block a user