mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-29 15:06:26 +02:00
Implemented SAN via Letsencrypt and Certbot
This commit is contained in:
@@ -1,22 +1,24 @@
|
||||
# nginx-redirect-www
|
||||
# Nginx WWW Redirect 🌐
|
||||
|
||||
## Description
|
||||
Automates the creation of Nginx server blocks that redirect all `www.` subdomains to their non-www equivalents. Simple, idempotent, and SEO-friendly! 🚀
|
||||
|
||||
## Overview
|
||||
The `nginx-redirect-www` role is designed to automate the process of setting up redirects from `www.domain.tld` to `domain.tld` for all domains and subdomains configured within the `{{nginx.directories.http.servers}}` directory. This role dynamically identifies configuration files following the pattern `*domain.tld.conf` and creates corresponding redirection rules.
|
||||
This role will:
|
||||
- **Discover** existing `*.conf` vhosts in your Nginx servers directory
|
||||
- **Filter** domains with or without your `primary_domain`
|
||||
- **Generate** redirect rules via the `nginx-redirect-domain` role
|
||||
- **Optionally** include a wildcard redirect template (experimental) ⭐️
|
||||
- **Clean up** leftover configs when running in cleanup mode 🧹
|
||||
|
||||
## Role Description
|
||||
This role performs several key tasks:
|
||||
1. **Find Configuration Files**: Locates all `.conf` files in the `{{nginx.directories.http.servers}}` directory that match the `*.*.conf` pattern, ensuring that only domain and subdomain configurations are selected.
|
||||
|
||||
2. **Filter Domain Names**: Processes each configuration file, extracting the domain names and removing both the `.conf` extension and the `{{nginx.directories.http.servers}}` path.
|
||||
All tasks are guarded by “run once” facts and `mode_cleanup` flags to avoid unintended re-runs or stale files.
|
||||
|
||||
3. **Prepare Redirect Domain Mappings**: Transforms the filtered domain names into a source-target mapping format, where `source` is `www.domain.tld` and `target` is `domain.tld`.
|
||||
## Purpose
|
||||
Ensure that any request to `www.example.com` automatically and permanently redirects to `https://example.com`, improving user experience, SEO, and certificate management. 🎯
|
||||
|
||||
4. **Include nginx-redirect-domain Role**: Applies the redirection configuration using the `nginx-redirect-domain` role with the dynamically generated domain mappings.
|
||||
|
||||
## Notes
|
||||
- This role is designed to work in environments where domain and subdomain configurations follow the naming pattern `*domain.tld.conf`.
|
||||
- It automatically excludes any configurations that begin with `www.`, preventing duplicate redirects.
|
||||
|
||||
---
|
||||
|
||||
This `nginx-redirect-www` role was crafted by [Kevin Veen-Birkenbach](https://www.veen.world) with insights and guidance provided by ChatGPT, an advanced AI language model from OpenAI. The development process, including the discussions with ChatGPT that shaped this role, can be [here](https://chat.openai.com/share/a68e3574-f543-467d-aea7-0895f0e00bbb) explored in detail.
|
||||
## Features
|
||||
- **Auto-Discovery**: Scans your Nginx `servers` directory for `.conf` files. 🔍
|
||||
- **Dynamic Redirects**: Builds `source: "www.domain"` → `target: "domain"` mappings on the fly. 🔧
|
||||
- **Wildcard Redirect**: Includes a templated wildcard server block for `www.*` domains (toggleable). ✨
|
||||
- **Cleanup Mode**: Removes the wildcard config file when `certbot_flavor` is set to `dedicated` and `mode_cleanup` is enabled. 🗑️
|
||||
- **Debug Output**: Optional `enable_debug` gives detailed variable dumps for troubleshooting. 🐛
|
||||
|
@@ -1,2 +1,26 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: "Kevin Veen-Birkenbach"
|
||||
description: "An Ansible role to redirect www subdomains to non-www domains in Nginx"
|
||||
license: "CyMaIS NonCommercial License (CNCL)"
|
||||
license_url: "https://s.veen.world/cncl"
|
||||
company: |
|
||||
Kevin Veen-Birkenbach
|
||||
Consulting & Coaching Solutions
|
||||
https://www.veen.world
|
||||
min_ansible_version: "2.9"
|
||||
platforms:
|
||||
- name: Archlinux
|
||||
versions:
|
||||
- rolling
|
||||
galaxy_tags:
|
||||
- nginx
|
||||
- redirect
|
||||
- www
|
||||
- wildcard
|
||||
- seo
|
||||
repository: "https://s.veen.world/cymais"
|
||||
issue_tracker_url: "https://s.veen.world/cymaisissues"
|
||||
documentation: "https://s.veen.world/cymais"
|
||||
dependencies:
|
||||
- nginx
|
||||
- nginx
|
@@ -1,87 +1,23 @@
|
||||
---
|
||||
- name: Find all .conf
|
||||
ansible.builtin.find:
|
||||
paths: "{{nginx.directories.http.servers}}"
|
||||
patterns: '*.*.conf'
|
||||
register: conf_files
|
||||
|
||||
# Filter all domains
|
||||
|
||||
- name: Filter domain names and remove .conf extension and path
|
||||
# 1. Filter all domains with the “www.” prefix
|
||||
- name: Filter www-prefixed domains from all_domains
|
||||
set_fact:
|
||||
filtered_domains: "{{ conf_files.files | map(attribute='path') | map('regex_search', domain_regex) | select('string') | map('regex_replace', path_regex, '') | map('regex_replace', '.conf$', '') | list }}"
|
||||
vars:
|
||||
domain_regex: "^{{nginx.directories.http.servers}}(?!www\\.)[^/]+\\.conf$"
|
||||
path_regex: "^{{nginx.directories.http.servers}}"
|
||||
www_domains: "{{ all_domains | select('match', '^www\\.') | list }}"
|
||||
|
||||
# Routine for domains with primary domain included
|
||||
|
||||
- name: Set filtered_domains_with_primary_domain
|
||||
# 2. Build redirect mappings (www.domain → domain)
|
||||
- name: Build redirect mappings for www domains
|
||||
set_fact:
|
||||
filtered_domains_with_primary_domain: "{{ filtered_domains | select('search', primary_domain + '$') | list }}"
|
||||
domain_mappings: >-
|
||||
{{ www_domains
|
||||
| map('regex_replace', '^www\\.(.+)$', '{ source: \"www.\\1\", target: \"\\1\" }')
|
||||
| map('from_yaml')
|
||||
| list
|
||||
}}
|
||||
|
||||
- name: Include nginx-redirect-domain role with dynamic domain mappings for domains with {{primary_domain}} included
|
||||
# 3. Include the nginx-redirect-domain role to apply these mappings
|
||||
- name: Include nginx-redirect-domain role for www-to-bare redirects
|
||||
include_role:
|
||||
name: nginx-redirect-domain
|
||||
vars:
|
||||
domain_mappings: "{{ filtered_domains_with_primary_domain | map('regex_replace', '^(.*)$', '{ source: \"www.\\1\", target: \"\\1\" }') | map('from_yaml') | list }}"
|
||||
when: not enable_wildcard_certificate | bool
|
||||
|
||||
- name: Include wildcard www. redirect for domains with {{primary_domain}} included
|
||||
vars:
|
||||
domain: "{{primary_domain}}"
|
||||
template:
|
||||
src: www.wildcard.conf.j2
|
||||
dest: "{{nginx_www_wildcard_configuration}}"
|
||||
notify: restart nginx
|
||||
when: enable_wildcard_certificate | bool
|
||||
|
||||
# Routine for domains without the primary domain included
|
||||
|
||||
- name: Set filtered_domains_without_primary_domain
|
||||
set_fact:
|
||||
filtered_domains_without_primary_domain: "{{ filtered_domains | reject('search', primary_domain + '$') | list }}"
|
||||
|
||||
- name: "Relevant variables for role: {{ role_path | basename }}"
|
||||
debug:
|
||||
msg:
|
||||
filtered_domains_with_primary_domain: "{{filtered_domains_with_primary_domain}}"
|
||||
filtered_domains: "{{filtered_domains}}"
|
||||
filtered_domains_without_primary_domain: "{{filtered_domains_without_primary_domain}}"
|
||||
when: enable_debug | bool
|
||||
|
||||
- name: Include nginx-redirect-domain role with dynamic domain mappings for domains without primary domain
|
||||
include_role:
|
||||
name: nginx-redirect-domain
|
||||
vars:
|
||||
domain_mappings: "{{ filtered_domains_without_primary_domain | map('regex_replace', '^(.*)$', '{ source: \"www.\\1\", target: \"\\1\" }') | map('from_yaml') | list }}"
|
||||
|
||||
|
||||
# Cleanup
|
||||
# Deactivated due to complexity
|
||||
#- name: Cleanup dedicated nginx configurations for www redirect configuration
|
||||
# file:
|
||||
# path: "{{ nginx.directories.http.servers }}{{ item.source }}.conf"
|
||||
# state: absent
|
||||
# # Filter: Only first-level subdomains of primary_domain
|
||||
# # Exclude the primary domain itself
|
||||
# # Transform for www redirection
|
||||
# loop: "{{ filtered_domains_with_primary_domain
|
||||
# | select('regex_search', '^[^.]+\\.' ~ primary_domain ~ '$')
|
||||
# | reject('equalto', primary_domain)
|
||||
# | map('regex_replace', '^(.*)$', '{ source: \"www.\\1\", target: \"\\1\" }')
|
||||
# | map('from_yaml')
|
||||
# | list }}"
|
||||
# notify: restart nginx
|
||||
# when:
|
||||
# - enable_wildcard_certificate | bool # Wildcard certificate must be enabled
|
||||
# - mode_cleanup | bool # Cleanup mode must be enabled
|
||||
|
||||
- name: Cleanup {{nginx_www_wildcard_configuration}}
|
||||
file:
|
||||
path: "{{nginx_www_wildcard_configuration}}"
|
||||
state: absent
|
||||
notify: restart nginx
|
||||
when:
|
||||
- not enable_wildcard_certificate | bool
|
||||
- mode_cleanup | bool
|
||||
domain_mappings: "{{ domain_mappings }}"
|
||||
when: certbot_flavor == 'dedicated'
|
||||
|
@@ -1,6 +0,0 @@
|
||||
server {
|
||||
server_name ~^www\.(?<domain>.+)$;
|
||||
{% include 'roles/letsencrypt/templates/ssl_header.j2' %}
|
||||
|
||||
return 301 https://$domain$request_uri;
|
||||
}
|
@@ -1 +0,0 @@
|
||||
nginx_www_wildcard_configuration: "{{nginx.directories.http.global}}www.wildcard.conf"
|
Reference in New Issue
Block a user