diff options
| author | Joshua Lusk <luskjh@gmail.com> | 2026-05-26 09:14:41 -0400 |
|---|---|---|
| committer | Joshua Lusk <luskjh@gmail.com> | 2026-05-26 09:14:41 -0400 |
| commit | 94b0799bc018132084cab540efb521454c918375 (patch) | |
| tree | f31e4937d71295981338e3bd36cee858a87a81f2 | |
| parent | 62c00bba0f4fdaeca96a9055b34d36b89cc8e34a (diff) | |
add https playbook
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | playbooks/https.yaml | 73 | ||||
| -rw-r--r-- | playbooks/templates/nginx/https.conf.j2 | 60 |
4 files changed, 138 insertions, 0 deletions
@@ -37,3 +37,7 @@ security: .PHONY: http http: $(BIN)/ansible-playbook -e @vault.yaml playbooks/http.yaml + +.PHONY: https +https: + $(BIN)/ansible-playbook -e @vault.yaml playbooks/https.yaml @@ -35,6 +35,7 @@ _Listed in applicable order._ | `bootstrap`<sup>*</sup> | Bootstrap access | | `security` | Security hardening | | `http` | Web server | +| `https` | SSL certificates | ### <sup>*</sup>Pre-bootstraped targets diff --git a/playbooks/https.yaml b/playbooks/https.yaml new file mode 100644 index 0000000..84146db --- /dev/null +++ b/playbooks/https.yaml @@ -0,0 +1,73 @@ +- name: SSL certificates + hosts: hollyhock + become: true + tasks: + - name: Install certbot + community.general.snap: + name: certbot + classic: true + state: present + + - name: Create symlink for certbot + ansible.builtin.file: + src: /snap/bin/certbot + dest: /usr/bin/certbot + state: link + + - name: Allow https traffic through firewall + community.general.ufw: + rule: allow + port: 443 + proto: tcp + + - name: Generate certificates + ansible.builtin.command: | + certbot certonly --nginx --non-interactive --agree-tos --email {{ admin_email }} + {% for domain in item.domains %}-d {{ domain }} {% endfor %} + loop: "{{ sites }}" + register: ssl_certs + failed_when: + - ssl_certs.rc != 0 + - "'Certificate not yet due for renewal' not in ssl_certs.stdout" + - "'Keeping the existing certificate' not in ssl_certs.stdout" + changed_when: + - "'Successfully received certificate' in ssl_certs.stdout" + - "'Deploying Certificate' in ssl_certs.stdout" + + - name: Copy initial https sites + ansible.builtin.template: + src: nginx/https.conf.j2 + dest: "/etc/nginx/sites-available/{{ item.name }}-https" + mode: "0644" + loop: "{{ sites }}" + + - name: Disable http nginx sites + ansible.builtin.file: + path: "/etc/nginx/sites-enabled/{{ item.name }}-http" + state: absent + loop: "{{ sites }}" + + - name: Check if final sites have been enabled + ansible.builtin.stat: + path: "/etc/nginx/sites-enabled/{{ item.name }}" + register: final_sites + loop: "{{ sites }}" + + - name: Enable https sites + ansible.builtin.file: + src: "/etc/nginx/sites-available/{{ item.item.name }}-https" + dest: "/etc/nginx/sites-enabled/{{ item.item.name }}-https" + state: link + loop: "{{ final_sites.results }}" + when: not item.stat.exists + notify: Test and restart nginx + + - name: Enable certbot timer + ansible.builtin.systemd: + name: snap.certbot.renew.timer + enabled: true + state: started + + handlers: + - name: Test and restart nginx + ansible.builtin.include_tasks: tasks/test_and_restart_nginx.yaml diff --git a/playbooks/templates/nginx/https.conf.j2 b/playbooks/templates/nginx/https.conf.j2 new file mode 100644 index 0000000..4962040 --- /dev/null +++ b/playbooks/templates/nginx/https.conf.j2 @@ -0,0 +1,60 @@ +server { + server_name {{ item.domains | join(' ') }}; + + listen 80; + listen [::]:80; + + return 301 https://$host$request_uri; +} + +server { + server_name {{ item.domains | join(' ') }}; + + listen 443 ssl; + listen [::]:443 ssl; + + root /var/www/html; + index index.nginx-debian.html; + + location / { + try_files $uri $uri/ =404; + } + + ssl_certificate /etc/letsencrypt/live/{{ item.domains[0] }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ item.domains[0] }}/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + + access_log /var/log/nginx/{{ item.name }}/access.log; + error_log /var/log/nginx/{{ item.name }}/error.log; +} +server { + server_name {{ item.domains | join(' ') }}; + + listen 80; + listen [::]:80; + + return 301 https://$host$request_uri; +} + +server { + server_name {{ item.domains | join(' ') }}; + + listen 443 ssl; + listen [::]:443 ssl; + + root /var/www/html; + index index.nginx-debian.html; + + location / { + try_files $uri $uri/ =404; + } + + ssl_certificate /etc/letsencrypt/live/{{ item.domains[0] }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ item.domains[0] }}/privkey.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + + access_log /var/log/nginx/{{ item.name }}/access.log; + error_log /var/log/nginx/{{ item.name }}/error.log; +} |
