mirror of
				https://github.com/kevinveenbirkenbach/computer-playbook.git
				synced 2025-10-31 18:29:21 +00:00 
			
		
		
		
	Refactor: migrate cmp/* and srv/* roles into sys-stk/* and sys-svc/* namespaces
- Removed obsolete 'cmp' category, introduced 'stk' category (fa-bars-staggered icon). - Renamed roles: * cmp-db-docker → sys-stk-back-stateful * cmp-docker-oauth2 → sys-stk-back-stateless * srv-domain-provision → sys-stk-front * cmp-db-docker-proxy → sys-stk-full-stateful * cmp-docker-proxy → sys-stk-full-stateless * cmp-rdbms → sys-svc-rdbms - Updated all include_role references, vars, templates and README.md files. - Adjusted run_once comments and variable paths accordingly. - Updated all web-app roles to use new sys-stk/* and sys-svc/* roles. Conversation: https://chatgpt.com/share/68b0ba66-09f8-800f-86fc-76c47009d431
This commit is contained in:
		
							
								
								
									
										35
									
								
								roles/sys-stk-front/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								roles/sys-stk-front/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| # Nginx Domain Setup 🚀 | ||||
|  | ||||
| ## Description | ||||
|  | ||||
| This role bootstraps **per-domain Nginx configuration**: it requests TLS certificates, applies global modifiers, deploys a ready-made vHost file, and can optionally lock down access via OAuth2. | ||||
|  | ||||
| ## Overview | ||||
|  | ||||
| A higher-level orchestration wrapper, *sys-stk-front* ties together several lower-level roles: | ||||
|  | ||||
| 1. **`sys-srv-web-inj-compose`** – applies global tweaks and includes.   | ||||
| 2. **`srv-tls-core`** – obtains Let’s Encrypt certificates.   | ||||
| 3. **Domain template deployment** – copies a Jinja2 vHost from *srv-proxy-core*.   | ||||
| 4. **`web-app-oauth2-proxy`** *(optional)* – protects the site with OAuth2. | ||||
|  | ||||
| The result is a complete, reproducible domain rollout in a single playbook task. | ||||
|  | ||||
| ## Purpose | ||||
|  | ||||
| Provide **one-stop, idempotent domain provisioning** for Nginx-based homelabs or small production environments. | ||||
|  | ||||
| ## Features | ||||
|  | ||||
| - **End-to-end TLS** — certificate retrieval and secure headers included.   | ||||
| - **Template-driven vHosts** — choose *basic* or *ws_generic* flavours (or your own).   | ||||
| - **Conditional OAuth2** — easily toggle authentication per application.   | ||||
| - **Handler-safe** — automatically triggers an Nginx reload when templates change.   | ||||
| - **Composable** — designed to be called repeatedly for many domains. | ||||
|  | ||||
| ## Credits 📝 | ||||
|  | ||||
| Developed and maintained by **Kevin Veen-Birkenbach**.   | ||||
| Learn more at <https://www.veen.world> | ||||
|  | ||||
| Part of the **Infinito.Nexus Project** — licensed under the [Infinito.Nexus NonCommercial License](https://s.infinito.nexus/license) | ||||
							
								
								
									
										5
									
								
								roles/sys-stk-front/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								roles/sys-stk-front/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| # default vhost flavour | ||||
| vhost_flavour:        "basic"               # valid: basic | ws_generic | ||||
|  | ||||
| # build the full template path from the flavour | ||||
| vhost_template_src:   "roles/srv-proxy-core/templates/vhost/{{ vhost_flavour }}.conf.j2" | ||||
							
								
								
									
										24
									
								
								roles/sys-stk-front/meta/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								roles/sys-stk-front/meta/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| galaxy_info: | ||||
|   author: "Kevin Veen-Birkenbach" | ||||
|   description: "Automated domain provisioning (TLS, vHost, OAuth2) for Nginx." | ||||
|   license: "Infinito.Nexus NonCommercial License" | ||||
|   license_url: "https://s.infinito.nexus/license" | ||||
|   company: | | ||||
|     Kevin Veen-Birkenbach | ||||
|     Consulting & Coaching Solutions | ||||
|     https://www.veen.world | ||||
|   min_ansible_version: "2.9" | ||||
|   platforms: | ||||
|   - name: Archlinux | ||||
|     versions: | ||||
|     - rolling | ||||
|   galaxy_tags: | ||||
|   - nginx | ||||
|   - tls | ||||
|   - letsencrypt | ||||
|   - oauth2 | ||||
|   - automation | ||||
|   - archlinux | ||||
|   repository: https://s.infinito.nexus/code | ||||
|   issue_tracker_url: https://s.infinito.nexus/issues | ||||
|   documentation: "https://docs.infinito.nexus/" | ||||
							
								
								
									
										51
									
								
								roles/sys-stk-front/tasks/01_cloudflare.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								roles/sys-stk-front/tasks/01_cloudflare.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| # Initialize cache dict (works within the play; persists if fact cache is enabled) | ||||
| - name: "Ensure cf_zone_ids cache dict exists" | ||||
|   set_fact: | ||||
|     cf_zone_ids: "{{ cf_zone_ids | default({}) }}" | ||||
|  | ||||
| # Use cached zone_id if available for the apex (to_primary_domain) | ||||
| - name: "Load cf_zone_id from cache if present" | ||||
|   set_fact: | ||||
|     cf_zone_id: "{{ (cf_zone_ids | default({})).get(domain | to_primary_domain, false) }}" | ||||
|  | ||||
| # Only look up from Cloudflare if we still don't have it | ||||
| - name: "Ensure Cloudflare Zone ID is known for '{{ domain }}'" | ||||
|   vars: | ||||
|     cf_api_url: "https://api.cloudflare.com/client/v4/zones" | ||||
|   ansible.builtin.uri: | ||||
|     url: "{{ cf_api_url }}?name={{ domain | to_primary_domain }}" | ||||
|     method: GET | ||||
|     headers: | ||||
|       Authorization: "Bearer {{ CLOUDFLARE_API_TOKEN }}" | ||||
|       Content-Type: "application/json" | ||||
|     return_content: yes | ||||
|   register: cf_zone_lookup_dev | ||||
|   changed_when: false | ||||
|   when: | ||||
|     - not cf_zone_id | ||||
|   no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" | ||||
|  | ||||
| - name: "Set fact cf_zone_id and update cache dict" | ||||
|   set_fact: | ||||
|     cf_zone_id: "{{ cf_zone_lookup_dev.json.result[0].id }}" | ||||
|     cf_zone_ids: >- | ||||
|       {{ (cf_zone_ids | default({})) | ||||
|          | combine({ (domain | to_primary_domain): cf_zone_lookup_dev.json.result[0].id }) }} | ||||
|   when: | ||||
|     - not cf_zone_id | ||||
|     - cf_zone_lookup_dev.json.result | length > 0 | ||||
|  | ||||
| - name: "Fail if no Cloudflare zone found for {{ domain | to_primary_domain }}" | ||||
|   ansible.builtin.fail: | ||||
|     msg: "No Cloudflare zone found for {{ domain | to_primary_domain }} — aborting!" | ||||
|   when: | ||||
|     - not cf_zone_id | ||||
|     - cf_zone_lookup_dev.json.result | length == 0 | ||||
|  | ||||
| - name: activate cloudflare cache development mode | ||||
|   include_tasks: "cloudflare/02_enable_cf_dev_mode.yml" | ||||
|   when: (ENVIRONMENT | lower) == 'development'  | ||||
|    | ||||
| - name: purge cloudflare domain cache | ||||
|   include_tasks: "cloudflare/01_cleanup.yml" | ||||
|   when: MODE_CLEANUP | bool | ||||
							
								
								
									
										13
									
								
								roles/sys-stk-front/tasks/cloudflare/01_cleanup.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								roles/sys-stk-front/tasks/cloudflare/01_cleanup.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| - name: "Purge everything from Cloudflare cache for domain {{ domain }}" | ||||
|   ansible.builtin.uri: | ||||
|     url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/purge_cache" | ||||
|     method: POST | ||||
|     headers: | ||||
|       Authorization: "Bearer {{ CLOUDFLARE_API_TOKEN }}" | ||||
|       Content-Type: "application/json" | ||||
|     body: | ||||
|       purge_everything: true | ||||
|     body_format: json | ||||
|     return_content: yes | ||||
|   async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" | ||||
|   poll:  "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" | ||||
| @@ -0,0 +1,35 @@ | ||||
| --- | ||||
| # Enables Cloudflare Development Mode (bypasses cache for ~3 hours). | ||||
| # Uses the same auth token as in 01_cleanup.yml: CLOUDFLARE_API_TOKEN | ||||
| # Assumes `domain` and (optionally) `cf_zone_id` are available. | ||||
| # Safe to run repeatedly; only changes when the mode is not already "on". | ||||
|  | ||||
| - name: "Read current Cloudflare development_mode setting" | ||||
|   ansible.builtin.uri: | ||||
|     url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode" | ||||
|     method: GET | ||||
|     headers: | ||||
|       Authorization: "Bearer {{ CLOUDFLARE_API_TOKEN }}" | ||||
|       Content-Type: "application/json" | ||||
|     return_content: yes | ||||
|   register: cf_dev_mode_current | ||||
|   when: ASYNC_ENABLED | bool | ||||
|  | ||||
| - name: "Enable Cloudflare Development Mode" | ||||
|   ansible.builtin.uri: | ||||
|     url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode" | ||||
|     method: PATCH | ||||
|     headers: | ||||
|       Authorization: "Bearer {{ CLOUDFLARE_API_TOKEN }}" | ||||
|       Content-Type: "application/json" | ||||
|     body: | ||||
|       value: "on" | ||||
|     body_format: json | ||||
|     return_content: yes | ||||
|   register: cf_dev_mode_enable | ||||
|   changed_when: > | ||||
|     ASYNC_ENABLED | bool and | ||||
|     cf_dev_mode_current.json.result.value is defined and | ||||
|     cf_dev_mode_current.json.result.value != 'on' | ||||
|   async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" | ||||
|   poll:  "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" | ||||
							
								
								
									
										42
									
								
								roles/sys-stk-front/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								roles/sys-stk-front/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| - block: | ||||
|   - name: Include dependency 'srv-proxy-core' | ||||
|     include_role: | ||||
|       name: srv-proxy-core | ||||
|     when: run_once_srv_proxy_core is not defined | ||||
|   - include_tasks: utils/run_once.yml | ||||
|   when: run_once_sys_stk_front is not defined | ||||
|  | ||||
| - include_tasks: "01_cloudflare.yml" | ||||
|   when: DNS_PROVIDER == "cloudflare" | ||||
|  | ||||
| - include_tasks: "{{ playbook_dir }}/tasks/utils/load_handlers.yml" | ||||
|   vars: | ||||
|     handler_role_name: "svc-prx-openresty" | ||||
|  | ||||
| - name: "include role for {{ domain }} to receive certificates and do the modification routines" | ||||
|   include_role: | ||||
|     name: srv-composer | ||||
|  | ||||
| - name: "Copy nginx config to {{ configuration_destination }}" | ||||
|   template: | ||||
|     src: "{{ vhost_template_src }}" | ||||
|     dest: "{{ configuration_destination }}" | ||||
|   register: nginx_conf | ||||
|   notify: restart openresty | ||||
|  | ||||
| - block: | ||||
|   - name: "Check if {{ domains | get_domain(application_id) }} is reachable (only if config unchanged)" | ||||
|     uri: | ||||
|       url: "{{ domains | get_url(application_id, WEB_PROTOCOL) }}" | ||||
|     register: site_check | ||||
|     failed_when: false | ||||
|     changed_when: false | ||||
|  | ||||
|   - name: Restart nginx if site is down | ||||
|     command: | ||||
|       cmd: "true" | ||||
|     notify: restart openresty | ||||
|     when: | ||||
|     - site_check.status is defined | ||||
|     - not site_check.status in [200,301,302] | ||||
|   when: not nginx_conf.changed | ||||
							
								
								
									
										1
									
								
								roles/sys-stk-front/vars/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								roles/sys-stk-front/vars/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| configuration_destination:  "{{ NGINX.DIRECTORIES.HTTP.SERVERS }}{{ domain }}.conf" | ||||
		Reference in New Issue
	
	Block a user