add nginx role
This commit is contained in:
13
roles/nginx/defaults/main.yml
Normal file
13
roles/nginx/defaults/main.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
|
||||
nginx_confs: []
|
||||
|
||||
nginx_certbot: true
|
||||
certbot_regenerate: false
|
||||
|
||||
nginx_proxy_headers:
|
||||
X-Forwarded-For: '$remote_addr'
|
||||
X-Forwarded-Proto: '$scheme'
|
||||
Host: '$host'
|
||||
Upgrade: '$http_upgrade'
|
||||
Connection: '$connection_upgrade'
|
||||
6
roles/nginx/handlers/main.yml
Normal file
6
roles/nginx/handlers/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
- name: Reload nginx
|
||||
ansible.builtin.systemd:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
46
roles/nginx/tasks/certbot.yml
Normal file
46
roles/nginx/tasks/certbot.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
|
||||
- name: Esnure certbot installed
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- certbot
|
||||
- python3-certbot-nginx
|
||||
state: present
|
||||
|
||||
- name: Check if certificate exists
|
||||
ansible.builtin.stat:
|
||||
path: /etc/letsencrypt/live/{{ ansible_fqdn }}/cert.pem
|
||||
register: cert
|
||||
|
||||
- name: Get current certificate info
|
||||
community.crypto.x509_certificate_info:
|
||||
path: /etc/letsencrypt/live/{{ ansible_fqdn }}/cert.pem
|
||||
register: certinfo
|
||||
|
||||
- name: Set fact to regenerate certificates if new domains are added
|
||||
ansible.builtin.set_fact:
|
||||
certbot_regenerate: true
|
||||
when: item.name is defined and 'DNS:' + item.name not in certinfo.subject_alt_name
|
||||
loop: "{{ nginx_servers }}"
|
||||
|
||||
- name: Generate new certificate if one doesn't exist.
|
||||
ansible.builtin.command: >
|
||||
certbot --nginx certonly
|
||||
--non-interactive
|
||||
--email {{ certbot_admin_email }}
|
||||
--agree-tos
|
||||
--expand
|
||||
--domains {{ ansible_fqdn }}{% for server in nginx_servers %}{% if server.name is defined %},{{ server.name }}{% endif %}{% endfor %}
|
||||
when: not cert.stat.exists or certbot_regenerate
|
||||
notify: Reload nginx
|
||||
|
||||
- name: Ensure certificate configured for nginx
|
||||
ansible.builtin.template:
|
||||
src: letsencrypt.conf.j2
|
||||
dest: /etc/nginx/conf.d/letsencrypt.conf
|
||||
mode: 0644
|
||||
notify: Reload nginx
|
||||
|
||||
- name: Add ssl header config to the list of configs
|
||||
ansible.builtin.set_fact:
|
||||
nginx_confs: "{{ nginx_confs + ['ssl-headers'] }}"
|
||||
38
roles/nginx/tasks/main.yml
Normal file
38
roles/nginx/tasks/main.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
|
||||
- name: Ensure nginx installed
|
||||
ansible.builtin.apt:
|
||||
name: nginx
|
||||
state: latest
|
||||
|
||||
- name: Ensure nginx default config disabled
|
||||
ansible.builtin.file:
|
||||
path: /etc/nginx/sites-enabled/default
|
||||
state: absent
|
||||
notify: Reload nginx
|
||||
|
||||
- name: Set up certbot
|
||||
ansible.builtin.include_tasks: certbot.yml
|
||||
when: nginx_certbot
|
||||
|
||||
- name: Ensure nginx configs in place
|
||||
ansible.builtin.template:
|
||||
src: "conf/{{ item }}.conf.j2"
|
||||
dest: "/etc/nginx/conf.d/{{ item }}.conf"
|
||||
mode: 0644
|
||||
loop: "{{ nginx_confs }}"
|
||||
notify: Reload nginx
|
||||
|
||||
- name: Ensure nginx main site configured
|
||||
ansible.builtin.template:
|
||||
src: "site.j2"
|
||||
dest: "/etc/nginx/sites-available/main"
|
||||
mode: 0644
|
||||
notify: Reload nginx
|
||||
|
||||
- name: Ensure nginx main site enabled
|
||||
ansible.builtin.file:
|
||||
src: "../sites-available/main"
|
||||
dest: "/etc/nginx/sites-enabled/main"
|
||||
state: link
|
||||
notify: Reload nginx
|
||||
12
roles/nginx/templates/conf/ssl-headers.conf.j2
Normal file
12
roles/nginx/templates/conf/ssl-headers.conf.j2
Normal file
@@ -0,0 +1,12 @@
|
||||
# {{ ansible_managed }}
|
||||
|
||||
# Strict Transport Security (HSTS), Tell browsers to use only https (adding includeSubDomains would also force subdomains to use HSTS)
|
||||
add_header Strict-Transport-Security "max-age=15552000; preload" always;
|
||||
|
||||
# Expect Certificate Transparency and -Stapling, Security measures for checking HTTPS-certificate validity/revocation
|
||||
add_header Expect-CT 'enforce; max-age=86400;' always;
|
||||
add_header Expect-Staple 'max-age=86400; preload' always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Xss-Protection "1; mode=block" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
5
roles/nginx/templates/letsencrypt.conf.j2
Normal file
5
roles/nginx/templates/letsencrypt.conf.j2
Normal file
@@ -0,0 +1,5 @@
|
||||
# {{ ansible_managed }}
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/{{ ansible_fqdn }}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/{{ ansible_fqdn }}/privkey.pem;
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/{{ ansible_fqdn }}/fullchain.pem;
|
||||
156
roles/nginx/templates/site.j2
Normal file
156
roles/nginx/templates/site.j2
Normal file
@@ -0,0 +1,156 @@
|
||||
# {{ ansible_managed }}
|
||||
|
||||
{% if nginx_upstreams is defined %}
|
||||
# Upstreams
|
||||
{% for upstream in nginx_upstreams | dict2items %}
|
||||
{% if upstream.value.servers | length != 0 %}
|
||||
upstream {{ upstream.key }} {
|
||||
{% if upstream.value.method is defined %}
|
||||
{{ upstream.value.method }};
|
||||
{% endif %}
|
||||
{% for server in upstream.value.servers %}
|
||||
{% if server | int != 0 %}
|
||||
server 127.0.0.1:{{ server }};
|
||||
{% else %}
|
||||
server {{ server }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if nginx_maps is defined %}
|
||||
{% for map in nginx_maps | dict2items %}
|
||||
{% if map.value.var | length != 0 %}
|
||||
map ${{ map.value.var }} ${{ map.key }} {
|
||||
{% for rule in map.value.rules | dict2items %}
|
||||
{{ rule.key }} {{ rule.value }};
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if nginx_certbot %}
|
||||
# HTTP -> HTTPS redirect
|
||||
server {
|
||||
listen 0.0.0.0:80 default_server;
|
||||
{% if ansible_default_ipv6.address is defined %}
|
||||
listen [::]:80 default_server;
|
||||
{% endif %}
|
||||
server_name {{ ansible_fqdn }};
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
# Websocket map
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
{% for server in nginx_servers %}
|
||||
server {
|
||||
{% for listener in server.listen | default([{}]) %}
|
||||
{% if listener.ip | default('all') == 'all' %}
|
||||
listen 0.0.0.0:{{ listener.port | default('443' if nginx_certbot else '80') }} {{ 'ssl http2 ' if nginx_certbot else '' }}{{ 'default_server' if server.name is not defined or server.name == ansible_fqdn }};
|
||||
{% if ansible_default_ipv6.address is defined %}
|
||||
listen [::]:{{ listener.port | default('443' if nginx_certbot else '80') }} {{ 'ssl http2 ' if nginx_certbot else '' }}{{ 'default_server' if server.name is not defined or server.name == ansible_fqdn }};
|
||||
{% endif %}
|
||||
server_name {{ server.name | default(ansible_fqdn) }};
|
||||
|
||||
{% elif listener.ip == 'localhost' %}
|
||||
listen 127.0.0.1:{{ listener.port }} default_server;
|
||||
{% if ansible_default_ipv6.address is defined %}
|
||||
listen [::1]:{{ listener.port }} default_server;
|
||||
{% endif %}
|
||||
server_name localhost;
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if server.return is defined %}
|
||||
# Sipmle returns
|
||||
{% for return in server.return %}
|
||||
location {{ return.location }} {
|
||||
return {{ return.type | default('200') }} '{{ return.content | to_json if return.content_type | default('plain') == 'json' else return.content }}';
|
||||
{% if return.headers is mapping %}
|
||||
{% for header in return.headers | dict2items %}
|
||||
add_header {{ header.key }} {{ header.value }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if server.reverse_proxy is defined %}
|
||||
# Reverse proxy
|
||||
{% for upstream in server.reverse_proxy %}
|
||||
{% if nginx_upstreams[upstream].servers | length != 0 %}
|
||||
|
||||
# {{ upstream }}
|
||||
{% for location in nginx_upstreams[upstream].locations | default([{'name': '/'}]) %}
|
||||
|
||||
{% if location.name | length != 0 %}
|
||||
location {{ location.name }} {
|
||||
proxy_pass http://{{ upstream }};
|
||||
{% if location.proxy_headers is mapping %}
|
||||
{% for header in location.proxy_headers | dict2items %}
|
||||
proxy_set_header {{ header.key }} {{ header.value }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if nginx_proxy_headers is mapping %}
|
||||
{% for header in nginx_proxy_headers | dict2items %}
|
||||
{% if location.proxy_headers[header.key] is not defined %}
|
||||
proxy_set_header {{ header.key }} {{ header.value }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if location.additional_options is defined %}
|
||||
{% for item in location.additional_options %}
|
||||
{{ item }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if server.reverse_proxy_map is defined %}
|
||||
# Mapping reverse proxy
|
||||
{% for map in server.reverse_proxy_map %}
|
||||
{% if nginx_maps[map].var | length != 0 %}
|
||||
|
||||
# {{ map }}
|
||||
{% for location in nginx_maps[map].locations %}
|
||||
|
||||
{% if location.name | length != 0 %}
|
||||
location {{ location.name }} {
|
||||
proxy_pass http://${{ map }};
|
||||
{% if nginx_proxy_headers is mapping %}
|
||||
{% for header in nginx_proxy_headers | dict2items %}
|
||||
proxy_set_header {{ header.key }} {{ header.value }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if location.additional_options is defined %}
|
||||
{% for item in location.additional_options %}
|
||||
{{ item }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
Reference in New Issue
Block a user