Compare commits
	
		
			14 Commits
		
	
	
		
			85a6c3894a
			...
			jellyfin
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ba44547066 | |||
| 9142254a57 | |||
| dfd93dd5f8 | |||
| 81d2ea447a | |||
| 9512212b84 | |||
| c67a39982e | |||
| f68f57d0cf | |||
| b9f9b0bf3c | |||
| 4f4a341b05 | |||
| cab6ab2d8e | |||
| 95f54b7f0a | |||
| 7522c333da | |||
| 344b79e97f | |||
| e4fed78193 | 
							
								
								
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,13 +1,3 @@ | ||||
| .vagrant | ||||
| .playbook | ||||
| /*.yml | ||||
| /*.yaml | ||||
| !backup.yml | ||||
| !moxie.yml | ||||
| !docker.yml | ||||
| !dockerbox.yml | ||||
| !hypervisor.yml | ||||
| !minecraft.yml | ||||
| !proxy.yml | ||||
| !unifi.yml | ||||
| /environments/ | ||||
|   | ||||
| @@ -8,7 +8,6 @@ | ||||
|     - docker | ||||
|     - traefik | ||||
|     - nextcloud | ||||
|     - gitea | ||||
|     - jenkins | ||||
|     - prometheus | ||||
|     - nginx | ||||
|   | ||||
| @@ -13,6 +13,7 @@ traefik_domain: traefik.vm.krislamo.org | ||||
| traefik_auth: admin:$apr1$T1l.BCFz$Jyg8msXYEAUi3LLH39I9d1 # admin:admin | ||||
| #traefik_acme_email: realemail@example.com # Let's Encrypt settings | ||||
| #traefik_production: true | ||||
| traefik_http_only: true # if behind reverse-proxy | ||||
|  | ||||
| # nextcloud | ||||
| nextcloud_version: stable | ||||
|   | ||||
							
								
								
									
										37
									
								
								dev/host_vars/mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								dev/host_vars/mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| base_domain: vm.krislamo.org | ||||
|  | ||||
| # base | ||||
| allow_reboot: false | ||||
| manage_network: false | ||||
|  | ||||
| # proxy | ||||
| proxy: | ||||
|   #production: true | ||||
|   dns_cloudflare: | ||||
|     opts: --test-cert | ||||
|     #email: realemail@example.com | ||||
|     #api_token: CLOUDFLARE_DNS01_API_TOKEN | ||||
|     wildcard_domains: | ||||
|       - "{{ base_domain }}" | ||||
|   servers: | ||||
|     - domain: "{{ traefik_domain }}" | ||||
|       proxy_pass: "http://127.0.0.1:8000" | ||||
|     - domain: "{{ jellyfin_domain }}" | ||||
|       proxy_pass: "http://127.0.0.1:8000" | ||||
|  | ||||
| # docker | ||||
| docker_users: | ||||
|   - vagrant | ||||
|  | ||||
| # traefik | ||||
| traefik_version: latest | ||||
| traefik_dashboard: true | ||||
| traefik_domain: "traefik.{{ base_domain }}" | ||||
| traefik_auth: admin:$apr1$T1l.BCFz$Jyg8msXYEAUi3LLH39I9d1 # admin:admin | ||||
| #traefik_acme_email: realemail@example.com # Let's Encrypt settings | ||||
| #traefik_production: true | ||||
| traefik_http_only: true # if behind reverse-proxy | ||||
|  | ||||
| # jellyfin | ||||
| jellyfin_domain: "jellyfin.{{ base_domain }}" | ||||
| jellyfin_version: latest | ||||
							
								
								
									
										11
									
								
								dev/mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								dev/mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| - name: Install Media Server | ||||
|   hosts: all | ||||
|   become: true | ||||
|   vars_files: | ||||
|     - host_vars/mediaserver.yml | ||||
|   roles: | ||||
|     - base | ||||
|     - proxy | ||||
|     - docker | ||||
|     - traefik | ||||
|     - jellyfin | ||||
| @@ -20,7 +20,6 @@ | ||||
|     - docker | ||||
|     - traefik | ||||
|     - nextcloud | ||||
|     - gitea | ||||
|     - jenkins | ||||
|     - prometheus | ||||
|     - nginx | ||||
|   | ||||
							
								
								
									
										9
									
								
								mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| - name: Install Media Server | ||||
|   hosts: mediaservers | ||||
|   become: true | ||||
|   roles: | ||||
|     - base | ||||
|     - proxy | ||||
|     - docker | ||||
|     - traefik | ||||
|     - jellyfin | ||||
							
								
								
									
										20
									
								
								roles/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								roles/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,20 +0,0 @@ | ||||
| /* | ||||
| !.gitignore | ||||
| !requirements.yml | ||||
| !base*/ | ||||
| !bitwarden*/ | ||||
| !docker*/ | ||||
| !gitea*/ | ||||
| !jenkins*/ | ||||
| !libvirt*/ | ||||
| !mariadb*/ | ||||
| !minecraft*/ | ||||
| !nextcloud*/ | ||||
| !nginx*/ | ||||
| !postgresql*/ | ||||
| !prometheus*/ | ||||
| !proxy*/ | ||||
| !rsnapshot*/ | ||||
| !traefik*/ | ||||
| !unifi*/ | ||||
| !wordpress*/ | ||||
| @@ -1,18 +1,24 @@ | ||||
| - name: Reboot host | ||||
|   reboot: | ||||
|   ansible.builtin.reboot: | ||||
|     msg: "Reboot initiated by Ansible" | ||||
|     connect_timeout: 5 | ||||
|   listen: reboot_host | ||||
|   when: allow_reboot | ||||
|  | ||||
| - name: Restart WireGuard | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: wg-quick@wg0 | ||||
|     state: restarted | ||||
|   listen: restart_wireguard | ||||
|  | ||||
| - name: Restart Fail2ban | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: fail2ban | ||||
|     state: restarted | ||||
|   listen: restart_fail2ban | ||||
|  | ||||
| - name: Restart ddclient | ||||
|   ansible.builtin.service: | ||||
|     name: ddclient | ||||
|     state: restarted | ||||
|   listen: restart_ddclient | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| - name: 'Install Ansible dependency: python3-apt' | ||||
|   shell: 'apt-get update && apt-get install python3-apt -y' | ||||
|   ansible.builtin.shell: 'apt-get update && apt-get install python3-apt -y' | ||||
|   args: | ||||
|     creates: /usr/lib/python3/dist-packages/apt | ||||
|     warn: false | ||||
|  | ||||
| - name: Install additional Ansible dependencies | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: "{{ item }}" | ||||
|     state: present | ||||
|     force_apt_get: true | ||||
| @@ -17,7 +17,7 @@ | ||||
|     - python3-psycopg2 | ||||
|  | ||||
| - name: Create Ansible's temporary remote directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "~/.ansible/tmp" | ||||
|     state: directory | ||||
|     mode: 0700 | ||||
|   | ||||
| @@ -1,22 +1,17 @@ | ||||
| - name: Install ddclient | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: ddclient | ||||
|     state: present | ||||
|  | ||||
| - name: Install ddclient settings | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: ddclient.conf.j2 | ||||
|     dest: /etc/ddclient.conf | ||||
|     mode: 0600 | ||||
|   register: ddclient_settings | ||||
|  | ||||
| - name: Start ddclient and enable on boot | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: ddclient | ||||
|     state: started | ||||
|     enabled: true | ||||
|  | ||||
| - name: Restart ddclient | ||||
|   service: | ||||
|     name: ddclient | ||||
|     state: restarted | ||||
|   when: ddclient_settings.changed | ||||
|   | ||||
| @@ -1,46 +1,48 @@ | ||||
| - name: Install the Uncomplicated Firewall | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: ufw | ||||
|     state: present | ||||
|  | ||||
| - name: Install Fail2ban | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: fail2ban | ||||
|     state: present | ||||
|  | ||||
| - name: Deny incoming traffic by default | ||||
|   ufw: | ||||
|   community.general.ufw: | ||||
|     default: deny | ||||
|     direction: incoming | ||||
|  | ||||
| - name: Allow outgoing traffic by default | ||||
|   ufw: | ||||
|   community.general.ufw: | ||||
|     default: allow | ||||
|     direction: outgoing | ||||
|  | ||||
| - name: Allow OpenSSH with rate limiting | ||||
|   ufw: | ||||
|   community.general.ufw: | ||||
|     name: ssh | ||||
|     rule: limit | ||||
|  | ||||
| - name: Remove Fail2ban defaults-debian.conf | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: /etc/fail2ban/jail.d/defaults-debian.conf | ||||
|     state: absent | ||||
|  | ||||
| - name: Install OpenSSH's Fail2ban jail | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: fail2ban-ssh.conf.j2 | ||||
|     dest: /etc/fail2ban/jail.d/sshd.conf | ||||
|     mode: 0640 | ||||
|   notify: restart_fail2ban | ||||
|  | ||||
| - name: Install Fail2ban IP allow list | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: fail2ban-allowlist.conf.j2 | ||||
|     dest: /etc/fail2ban/jail.d/allowlist.conf | ||||
|     mode: 0640 | ||||
|   when: fail2ban_ignoreip is defined | ||||
|   notify: restart_fail2ban | ||||
|  | ||||
| - name: Enable firewall | ||||
|   ufw: | ||||
|   community.general.ufw: | ||||
|     state: enabled | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| - name: Install msmtp | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: "{{ item }}" | ||||
|     state: present | ||||
|   loop: | ||||
| @@ -8,12 +8,13 @@ | ||||
|     - mailutils | ||||
|  | ||||
| - name: Install msmtp configuration | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: msmtprc.j2 | ||||
|     dest: /root/.msmtprc | ||||
|     mode: 0700 | ||||
|     mode: 0600 | ||||
|  | ||||
| - name: Install /etc/aliases | ||||
|   copy: | ||||
|   ansible.builtin.copy: | ||||
|     dest: /etc/aliases | ||||
|     content: "root: {{ mail.rootalias }}" | ||||
|     mode: 0644 | ||||
|   | ||||
| @@ -1,24 +1,31 @@ | ||||
| - import_tasks: ansible.yml | ||||
| - name: Import Ansible tasks | ||||
|   ansible.builtin.import_tasks: ansible.yml | ||||
|   tags: ansible | ||||
|  | ||||
| - import_tasks: system.yml | ||||
| - name: Import System tasks | ||||
|   ansible.builtin.import_tasks: system.yml | ||||
|   tags: system | ||||
|  | ||||
| - import_tasks: firewall.yml | ||||
| - name: Import Firewall tasks | ||||
|   ansible.builtin.import_tasks: firewall.yml | ||||
|   tags: firewall | ||||
|  | ||||
| - import_tasks: network.yml | ||||
| - name: Import Network tasks | ||||
|   ansible.builtin.import_tasks: network.yml | ||||
|   tags: network | ||||
|   when: manage_network | ||||
|  | ||||
| - import_tasks: mail.yml | ||||
| - name: Import Mail tasks | ||||
|   ansible.builtin.import_tasks: mail.yml | ||||
|   tags: mail | ||||
|   when: mail is defined | ||||
|  | ||||
| - import_tasks: ddclient.yml | ||||
| - name: Import ddclient tasks | ||||
|   ansible.builtin.import_tasks: ddclient.yml | ||||
|   tags: ddclient | ||||
|   when: ddclient is defined | ||||
|  | ||||
| - import_tasks: wireguard.yml | ||||
| - name: Import WireGuard tasks | ||||
|   ansible.builtin.import_tasks: wireguard.yml | ||||
|   tags: wireguard | ||||
|   when: wireguard is defined | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| - name: Install network interfaces file | ||||
|   copy: | ||||
|   ansible.builtin.copy: | ||||
|     src: network-interfaces.cfg | ||||
|     dest: /etc/network/interfaces | ||||
|     owner: root | ||||
| @@ -7,8 +7,9 @@ | ||||
|     mode: '0644' | ||||
|  | ||||
| - name: Install network interfaces | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: "interface.j2" | ||||
|     dest: "/etc/network/interfaces.d/{{ item.name }}" | ||||
|     mode: 0400 | ||||
|   loop: "{{ interfaces }}" | ||||
|   notify: reboot_host | ||||
|   | ||||
							
								
								
									
										25
									
								
								roles/base/tasks/samba.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								roles/base/tasks/samba.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| - name: Install Samba | ||||
|   ansible.builtin.apt: | ||||
|     name: samba | ||||
|     state: present | ||||
|  | ||||
| - name: Create Samba users | ||||
|   ansible.builtin.command: "smbpasswd -a -s {{ item.name }}" | ||||
|   args: | ||||
|     stdin: "{{ item.password }}\n{{ item.password }}" | ||||
|   loop: "{{ samba.users }}" | ||||
|   register: samba_users | ||||
|   changed_when: "'User added' in samba_users.stdout" | ||||
|  | ||||
| - name: Ensure share directories exist | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ item.path }}" | ||||
|     state: directory | ||||
|     mode: 0755 | ||||
|   loop: "{{ samba.shares }}" | ||||
|  | ||||
| - name: Configure Samba shares | ||||
|   ansible.builtin.template: | ||||
|     src: smb.conf.j2 | ||||
|     dest: /etc/samba/smb.conf | ||||
|   notify: samba_restart | ||||
| @@ -1,17 +1,18 @@ | ||||
| - name: Install useful software | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: "{{ packages }}" | ||||
|     state: present | ||||
|     update_cache: true | ||||
|  | ||||
| - name: Manage root authorized_keys | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: authorized_keys.j2 | ||||
|     dest: /root/.ssh/authorized_keys | ||||
|     mode: 0400 | ||||
|   when: authorized_keys is defined | ||||
|  | ||||
| - name: Manage filesystem mounts | ||||
|   mount: | ||||
|   ansible.posix.mount: | ||||
|     path: "{{ item.path }}" | ||||
|     src: "UUID={{ item.uuid }}" | ||||
|     fstype: "{{ item.fstype }}" | ||||
|   | ||||
| @@ -1,35 +1,37 @@ | ||||
| - name: Install WireGuard | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: wireguard | ||||
|     state: present | ||||
|     update_cache: true | ||||
|  | ||||
| - name: Generate WireGuard keys | ||||
|   shell: wg genkey | tee privatekey | wg pubkey > publickey | ||||
|   ansible.builtin.shell: | | ||||
|     set -o pipefail | ||||
|     wg genkey | tee privatekey | wg pubkey > publickey | ||||
|   args: | ||||
|     chdir: /etc/wireguard/ | ||||
|     creates: /etc/wireguard/privatekey | ||||
|  | ||||
| - name: Grab WireGuard private key for configuration | ||||
|   slurp: | ||||
|   ansible.builtin.slurp: | ||||
|     src: /etc/wireguard/privatekey | ||||
|   register: wgkey | ||||
|  | ||||
| - name: Install WireGuard configuration | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: wireguard.j2 | ||||
|     dest: /etc/wireguard/wg0.conf | ||||
|   notify: | ||||
|     - restart_wireguard | ||||
|     mode: 0400 | ||||
|   notify: restart_wireguard | ||||
|  | ||||
| - name: Start WireGuard interface | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: wg-quick@wg0 | ||||
|     state: started | ||||
|     enabled: true | ||||
|  | ||||
| - name: Add WireGuard firewall rule | ||||
|   ufw: | ||||
|   community.general.ufw: | ||||
|     rule: allow | ||||
|     port: "{{ wireguard.listenport }}" | ||||
|     proto: tcp | ||||
|   | ||||
							
								
								
									
										19
									
								
								roles/base/templates/smb.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								roles/base/templates/smb.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| [global] | ||||
|    workgroup = WORKGROUP | ||||
|    server string = Samba Server %v | ||||
|    netbios name = {{ ansible_hostname }} | ||||
|    security = user | ||||
|    map to guest = bad user | ||||
|    dns proxy = no | ||||
| {% for user in samba.users %} | ||||
|    smb encrypt = {{ 'mandatory' if user.encrypt | default(false) else 'disabled' }} | ||||
| {% endfor %} | ||||
|  | ||||
| {% for share in samba.shares %} | ||||
| [{{ share.name }}] | ||||
|    path = {{ share.path }} | ||||
|    browsable = yes | ||||
|    guest ok = no | ||||
|    read only = {{ 'yes' if share.read_only | default(false) else 'no' }} | ||||
|    valid users = {{ share.valid_users }} | ||||
| {% endfor %} | ||||
| @@ -1,15 +1,15 @@ | ||||
| - name: Stop Bitwarden for rebuild | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: "{{ bitwarden_name }}" | ||||
|     state: stopped | ||||
|   listen: rebuild_bitwarden | ||||
|  | ||||
| - name: Rebuild Bitwarden | ||||
|   shell: "{{ bitwarden_root }}/bitwarden.sh rebuild" | ||||
|   ansible.builtin.shell: "{{ bitwarden_root }}/bitwarden.sh rebuild" | ||||
|   listen: rebuild_bitwarden | ||||
|  | ||||
| - name: Start Bitwarden after rebuild | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: "{{ bitwarden_name }}" | ||||
|     state: started | ||||
|     enabled: true | ||||
|   | ||||
| @@ -1,40 +1,40 @@ | ||||
| - name: Install expect | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: expect | ||||
|     state: present | ||||
|  | ||||
| - name: Create Bitwarden directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ bitwarden_root }}" | ||||
|     state: directory | ||||
|  | ||||
| - name: Download Bitwarden script | ||||
|   get_url: | ||||
|   ansible.builtin.get_url: | ||||
|     url: "https://raw.githubusercontent.com/\ | ||||
|           bitwarden/self-host/master/bitwarden.sh" | ||||
|     dest: "{{ bitwarden_root }}" | ||||
|     mode: u+x | ||||
|  | ||||
| - name: Install Bitwarden script wrapper | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: bw_wrapper.j2 | ||||
|     dest: "{{ bitwarden_root }}/bw_wrapper" | ||||
|     mode: u+x | ||||
|  | ||||
| - name: Run Bitwarden installation script | ||||
|   shell: "{{ bitwarden_root }}/bw_wrapper" | ||||
|   ansible.builtin.shell: "{{ bitwarden_root }}/bw_wrapper" | ||||
|   args: | ||||
|     creates: "{{ bitwarden_root }}/bwdata/config.yml" | ||||
|  | ||||
| - name: Install docker-compose override | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: compose.override.yml.j2 | ||||
|     dest: "{{ bitwarden_root }}/bwdata/docker/docker-compose.override.yml" | ||||
|   when: traefik_version is defined | ||||
|   notify: rebuild_bitwarden | ||||
|  | ||||
| - name: Disable bitwarden-nginx HTTP on 80 | ||||
|   replace: | ||||
|   ansible.builtin.replace: | ||||
|     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||
|     regexp: "^http_port: 80$" | ||||
|     replace: "http_port: 127.0.0.1:8080" | ||||
| @@ -42,7 +42,7 @@ | ||||
|   notify: rebuild_bitwarden | ||||
|  | ||||
| - name: Disable bitwarden-nginx HTTPS on 443 | ||||
|   replace: | ||||
|   ansible.builtin.replace: | ||||
|     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||
|     regexp: "^https_port: 443$" | ||||
|     replace: "https_port: 127.0.0.1:8443" | ||||
| @@ -50,7 +50,7 @@ | ||||
|   notify: rebuild_bitwarden | ||||
|  | ||||
| - name: Disable Bitwarden managed Lets Encrypt | ||||
|   replace: | ||||
|   ansible.builtin.replace: | ||||
|     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||
|     regexp: "^ssl_managed_lets_encrypt: true$" | ||||
|     replace: "ssl_managed_lets_encrypt: false" | ||||
| @@ -58,7 +58,7 @@ | ||||
|   notify: rebuild_bitwarden | ||||
|  | ||||
| - name: Disable Bitwarden managed SSL | ||||
|   replace: | ||||
|   ansible.builtin.replace: | ||||
|     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||
|     regexp: "^ssl: true$" | ||||
|     replace: "ssl: false" | ||||
| @@ -66,39 +66,39 @@ | ||||
|   notify: rebuild_bitwarden | ||||
|  | ||||
| - name: Define reverse proxy servers | ||||
|   lineinfile: | ||||
|   ansible.builtin.lineinfile: | ||||
|     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||
|     line: "- {{ bitwarden_realips }}" | ||||
|     insertafter: "^real_ips" | ||||
|   notify: rebuild_bitwarden | ||||
|  | ||||
| - name: Install Bitwarden systemd service | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: bitwarden.service.j2 | ||||
|     dest: "/etc/systemd/system/{{ bitwarden_name }}.service" | ||||
|   register: bitwarden_systemd | ||||
|   notify: rebuild_bitwarden | ||||
|  | ||||
| - name: Create Bitwarden's initial logging directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ bitwarden_logs_identity }}" | ||||
|     state: directory | ||||
|   register: bitwarden_logs | ||||
|  | ||||
| - name: Create Bitwarden's initial log file | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ bitwarden_logs_identity }}/{{ bitwarden_logs_identity_date }}.txt" | ||||
|     state: touch | ||||
|   when: bitwarden_logs.changed | ||||
|  | ||||
| - name: Install Bitwarden's Fail2ban jail | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: fail2ban-jail.conf.j2 | ||||
|     dest: /etc/fail2ban/jail.d/bitwarden.conf | ||||
|   notify: restart_fail2ban | ||||
|  | ||||
| - name: Reload systemd manager configuration | ||||
|   systemd: | ||||
|   ansible.builtin.systemd: | ||||
|     daemon_reload: true | ||||
|   when: bitwarden_systemd.changed | ||||
|   notify: rebuild_bitwarden | ||||
|   | ||||
							
								
								
									
										4
									
								
								roles/docker/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								roles/docker/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| - name: Reload systemd manager configuration | ||||
|   ansible.builtin.systemd: | ||||
|     daemon_reload: true | ||||
|   listen: compose_systemd | ||||
| @@ -1,27 +1,24 @@ | ||||
| - name: Install Docker | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: ['docker.io', 'docker-compose'] | ||||
|     state: present | ||||
|     update_cache: true | ||||
|  | ||||
| - name: Create docker-compose root | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ docker_compose_root }}" | ||||
|     state: directory | ||||
|     mode: 0500 | ||||
|  | ||||
| - name: Install docker-compose systemd service | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: docker-compose.service.j2 | ||||
|     dest: "/etc/systemd/system/{{ docker_compose_service }}@.service" | ||||
|   register: compose_systemd | ||||
|  | ||||
| - name: Reload systemd manager configuration | ||||
|   systemd: | ||||
|     daemon_reload: true | ||||
|   when: compose_systemd.changed | ||||
|     mode: 0400 | ||||
|   notify: compose_systemd | ||||
|  | ||||
| - name: Add users to docker group | ||||
|   user: | ||||
|   ansible.builtin.user: | ||||
|     name: "{{ item }}" | ||||
|     groups: docker | ||||
|     append: true | ||||
| @@ -29,7 +26,7 @@ | ||||
|   when: docker_users is defined | ||||
|  | ||||
| - name: Start Docker and enable on boot | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: docker | ||||
|     state: started | ||||
|     enabled: true | ||||
|   | ||||
| @@ -5,7 +5,7 @@ gitea_webport: "3000" | ||||
| gitea_ssh: "127.0.0.1:{{ gitea_sshport }}" | ||||
| gitea_web: "127.0.0.1:{{ gitea_webport }}" | ||||
| gitea_volume: "{{ gitea_name }}" | ||||
| gitea_rooturl: "http://{{ gitea_domain }}" | ||||
| gitea_rooturl: "https://{{ gitea_domain }}" | ||||
| gitea_signup: true | ||||
|  | ||||
| # database settings | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| - name: Restart Gitea | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: "{{ docker_compose_service }}@{{ gitea_name }}" | ||||
|     state: restarted | ||||
|   listen: restart_gitea | ||||
|   | ||||
| @@ -1,16 +1,16 @@ | ||||
| - name: Create Gitea directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ gitea_root }}" | ||||
|     state: directory | ||||
|  | ||||
| - name: Create Gitea database | ||||
|   mysql_db: | ||||
|   community.mysql.mysql_db: | ||||
|     name: "{{ gitea_dbname }}" | ||||
|     state: present | ||||
|     login_unix_socket: /var/run/mysqld/mysqld.sock | ||||
|  | ||||
| - name: Create Gitea database user | ||||
|   mysql_user: | ||||
|   community.mysql.mysql_user: | ||||
|     name: "{{ gitea_dbuser }}" | ||||
|     password: "{{ gitea_dbpass }}" | ||||
|     host: '%' | ||||
| @@ -19,93 +19,93 @@ | ||||
|     login_unix_socket: /var/run/mysqld/mysqld.sock | ||||
|  | ||||
| - name: Create git user | ||||
|   user: | ||||
|   ansible.builtin.user: | ||||
|     name: git | ||||
|     state: present | ||||
|  | ||||
| - name: Git user uid | ||||
|   getent: | ||||
|   ansible.builtin.getent: | ||||
|     database: passwd | ||||
|     key: git | ||||
|  | ||||
| - name: Git user gid | ||||
|   getent: | ||||
|   ansible.builtin.getent: | ||||
|     database: group | ||||
|     key: git | ||||
|  | ||||
| - name: Create git's .ssh directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: /home/git/.ssh | ||||
|     state: directory | ||||
|  | ||||
| - name: Generate git's SSH keys | ||||
|   openssh_keypair: | ||||
|   community.crypto.openssh_keypair: | ||||
|     path: /home/git/.ssh/id_rsa | ||||
|  | ||||
| - name: Find git's public SSH key | ||||
|   slurp: | ||||
|   ansible.builtin.slurp: | ||||
|     src: /home/git/.ssh/id_rsa.pub | ||||
|   register: git_rsapub | ||||
|  | ||||
| - name: Get stats on git's authorized_keys file | ||||
|   stat: | ||||
|   ansible.builtin.stat: | ||||
|     path: /home/git/.ssh/authorized_keys | ||||
|   register: git_authkeys | ||||
|  | ||||
| - name: Create git's authorized_keys file | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: /home/git/.ssh/authorized_keys | ||||
|     state: touch | ||||
|   when: not git_authkeys.stat.exists | ||||
|  | ||||
| - name: Add git's public SSH key to authorized_keys | ||||
|   lineinfile: | ||||
|   ansible.builtin.lineinfile: | ||||
|     path: /home/git/.ssh/authorized_keys | ||||
|     regex: "^ssh-rsa" | ||||
|     line: "{{ git_rsapub['content'] | b64decode }}" | ||||
|  | ||||
| - name: Create Gitea host script for SSH | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: gitea.sh.j2 | ||||
|     dest: /usr/local/bin/gitea | ||||
|     mode: 0755 | ||||
|  | ||||
| - name: Install Gitea's docker-compose file | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: docker-compose.yml.j2 | ||||
|     dest: "{{ gitea_root }}/docker-compose.yml" | ||||
|   notify: restart_gitea | ||||
|  | ||||
| - name: Install Gitea's docker-compose variables | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: compose-env.j2 | ||||
|     dest: "{{ gitea_root }}/.env" | ||||
|   notify: restart_gitea | ||||
|  | ||||
| - name: Create Gitea's logging directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     name: /var/log/gitea | ||||
|     state: directory | ||||
|  | ||||
| - name: Create Gitea's initial log file | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     name: /var/log/gitea/gitea.log | ||||
|     state: touch | ||||
|  | ||||
| - name: Install Gitea's Fail2ban filter | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: fail2ban-filter.conf.j2 | ||||
|     dest: /etc/fail2ban/filter.d/gitea.conf | ||||
|   notify: restart_fail2ban | ||||
|  | ||||
| - name: Install Gitea's Fail2ban jail | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: fail2ban-jail.conf.j2 | ||||
|     dest: /etc/fail2ban/jail.d/gitea.conf | ||||
|   notify: restart_fail2ban | ||||
|  | ||||
| - name: Start and enable Gitea service | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: "{{ docker_compose_service }}@{{ gitea_name }}" | ||||
|     state: started | ||||
|     enabled: true | ||||
|   | ||||
							
								
								
									
										5
									
								
								roles/jellyfin/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								roles/jellyfin/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| jellyfin_name: jellyfin | ||||
| jellyfin_volume: "{{ jellyfin_name }}" | ||||
| jellyfin_router: "{{ jellyfin_name }}" | ||||
| jellyfin_rooturl: "https://{{ jellyfin_domain }}" | ||||
| jellyfin_root: "{{ docker_compose_root }}/{{ jellyfin_name }}" | ||||
							
								
								
									
										5
									
								
								roles/jellyfin/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								roles/jellyfin/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| - name: Restart Jellyfin | ||||
|   ansible.builtin.service: | ||||
|     name: "{{ docker_compose_service }}@{{ jellyfin_name }}" | ||||
|     state: restarted | ||||
|   listen: restart_jellyfin | ||||
							
								
								
									
										40
									
								
								roles/jellyfin/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								roles/jellyfin/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| - name: Create Jellyfin directory | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ jellyfin_root }}" | ||||
|     state: directory | ||||
|     mode: 0500 | ||||
|  | ||||
| - name: Create jellyfin user | ||||
|   ansible.builtin.user: | ||||
|     name: jellyfin | ||||
|     state: present | ||||
|  | ||||
| - name: Get user jellyfin uid | ||||
|   ansible.builtin.getent: | ||||
|     database: passwd | ||||
|     key: jellyfin | ||||
|  | ||||
| - name: Get user jellyfin gid | ||||
|   ansible.builtin.getent: | ||||
|     database: group | ||||
|     key: jellyfin | ||||
|  | ||||
| - name: Install Jellyfin's docker-compose file | ||||
|   ansible.builtin.template: | ||||
|     src: docker-compose.yml.j2 | ||||
|     dest: "{{ jellyfin_root }}/docker-compose.yml" | ||||
|     mode: 0400 | ||||
|   notify: restart_jellyfin | ||||
|  | ||||
| - name: Install Jellyfin's docker-compose variables | ||||
|   ansible.builtin.template: | ||||
|     src: compose-env.j2 | ||||
|     dest: "{{ jellyfin_root }}/.env" | ||||
|     mode: 0400 | ||||
|   notify: restart_jellyfin | ||||
|  | ||||
| - name: Start and enable Jellyfin service | ||||
|   ansible.builtin.service: | ||||
|     name: "{{ docker_compose_service }}@{{ jellyfin_name }}" | ||||
|     state: started | ||||
|     enabled: true | ||||
							
								
								
									
										5
									
								
								roles/jellyfin/templates/compose-env.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								roles/jellyfin/templates/compose-env.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| # {{ ansible_managed }} | ||||
| jellyfin_version={{ jellyfin_version }} | ||||
| jellyfin_name={{ jellyfin_name }} | ||||
| jellyfin_domain={{ jellyfin_domain }} | ||||
| jellyfin_rooturl={{ jellyfin_rooturl }} | ||||
							
								
								
									
										29
									
								
								roles/jellyfin/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								roles/jellyfin/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| version: '3.7' | ||||
|  | ||||
| volumes: | ||||
|   {{ jellyfin_volume }}: | ||||
|  | ||||
| networks: | ||||
|   traefik: | ||||
|     external: true | ||||
|  | ||||
| services: | ||||
|   jellyfin: | ||||
|     image: "jellyfin/jellyfin:${jellyfin_version}" | ||||
|     container_name: "${jellyfin_name}" | ||||
|     networks: | ||||
|       - traefik | ||||
|     labels: | ||||
|       - "traefik.http.routers.{{ jellyfin_router }}.rule=Host(`{{ jellyfin_domain }}`)" | ||||
| {% if traefik_http_only %} | ||||
|       - "traefik.http.routers.{{ jellyfin_router }}.entrypoints=web" | ||||
| {% else %} | ||||
|       - "traefik.http.routers.{{ jellyfin_router }}.entrypoints=websecure" | ||||
| {% endif %} | ||||
|       - "traefik.http.services.{{ jellyfin_router }}.loadbalancer.server.port=8096" | ||||
|       - "traefik.docker.network=traefik" | ||||
|       - "traefik.enable=true" | ||||
|     volumes: | ||||
|       - ./config:/config | ||||
|       - ./cache:/cache | ||||
|       - {{ jellyfin_volume }}:/media | ||||
| @@ -1,5 +1,5 @@ | ||||
| - name: Create Jenkins user | ||||
|   user: | ||||
|   ansible.builtin.user: | ||||
|     name: "{{ jenkins_user }}" | ||||
|     state: present | ||||
|     shell: /bin/bash | ||||
| @@ -7,25 +7,25 @@ | ||||
|     generate_ssh_key: true | ||||
|  | ||||
| - name: Set Jenkins authorized key | ||||
|   authorized_key: | ||||
|   ansible.posix.authorized_key: | ||||
|     user: jenkins | ||||
|     state: present | ||||
|     exclusive: true | ||||
|     key: "{{ jenkins_sshkey }}" | ||||
|  | ||||
| - name: Give Jenkins user passwordless sudo | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: jenkins_sudoers.j2 | ||||
|     dest: /etc/sudoers.d/{{ jenkins_user }} | ||||
|     validate: "visudo -cf %s" | ||||
|     mode: 0440 | ||||
|  | ||||
| - name: Install Ansible | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: ansible | ||||
|     state: present | ||||
|  | ||||
| - name: Install Java | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: default-jre | ||||
|     state: present | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| - import_tasks: agent.yml | ||||
| - ansible.builtin.import_tasks: agent.yml | ||||
|   when: jenkins_sshkey is defined | ||||
|  | ||||
| - import_tasks: server.yml | ||||
| - ansible.builtin.import_tasks: server.yml | ||||
|   when: jenkins_domain is defined | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| - name: Create Jenkin's directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ jenkins_root }}" | ||||
|     state: directory | ||||
|     owner: "1000" | ||||
|     group: "1000" | ||||
|  | ||||
| - name: Start Jenkins Container | ||||
|   docker_container: | ||||
|   community.general.docker_container: | ||||
|     name: "{{ jenkins_name }}" | ||||
|     image: jenkins/jenkins:{{ jenkins_version }} | ||||
|     state: started | ||||
|   | ||||
| @@ -1,15 +1,15 @@ | ||||
| - name: Install QEMU/KVM | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: qemu-kvm | ||||
|     state: present | ||||
|  | ||||
| - name: Install Libvirt | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: ["libvirt-clients", "libvirt-daemon-system"] | ||||
|     state: present | ||||
|  | ||||
| - name: Add users to libvirt group | ||||
|   user: | ||||
|   ansible.builtin.user: | ||||
|     name: "{{ item }}" | ||||
|     groups: libvirt | ||||
|     append: yes | ||||
| @@ -17,12 +17,12 @@ | ||||
|   when: libvirt_users is defined | ||||
|  | ||||
| - name: Check for NODOWNLOAD file | ||||
|   stat: | ||||
|   ansible.builtin.stat: | ||||
|     path: /var/lib/libvirt/images/NODOWNLOAD | ||||
|   register: NODOWNLOAD | ||||
|  | ||||
| - name: Download GNU/Linux ISOs | ||||
|   get_url: | ||||
|   ansible.builtin.get_url: | ||||
|     url: "{{ item.url }}" | ||||
|     dest: /var/lib/libvirt/images | ||||
|     checksum: "{{ item.hash }}" | ||||
| @@ -34,7 +34,7 @@ | ||||
|  | ||||
| # Prevent downloaded ISOs from being rehashed every run | ||||
| - name: Create NODOWNLOAD file | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: /var/lib/libvirt/images/NODOWNLOAD | ||||
|     state: touch | ||||
|   when: download_isos.changed | ||||
|   | ||||
| @@ -1,23 +1,23 @@ | ||||
| - name: Install MariaDB | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: mariadb-server | ||||
|     state: present | ||||
|  | ||||
| - name: Change the bind-address to allow Docker | ||||
|   lineinfile: | ||||
|   ansible.builtin.lineinfile: | ||||
|     path: /etc/mysql/mariadb.conf.d/50-server.cnf | ||||
|     regex: "^bind-address" | ||||
|     line: "bind-address            = 0.0.0.0" | ||||
|   register: mariadb_conf | ||||
|  | ||||
| - name: Restart MariaDB | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: mariadb | ||||
|     state: restarted | ||||
|   when: mariadb_conf.changed | ||||
|  | ||||
| - name: Allow database connections | ||||
|   ufw: | ||||
|   community.general.ufw: | ||||
|     rule: allow | ||||
|     port: "3306" | ||||
|     proto: tcp | ||||
|   | ||||
| @@ -1,28 +1,28 @@ | ||||
| - name: Install GPG | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: gpg | ||||
|     state: present | ||||
|  | ||||
| - name: Add AdoptOpenJDK's signing key | ||||
|   apt_key: | ||||
|   ansible.builtin.apt_key: | ||||
|     id: 8ED17AF5D7E675EB3EE3BCE98AC3B29174885C03 | ||||
|     url: https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | ||||
|  | ||||
| - name: Install AdoptOpenJDK repository | ||||
|   apt_repository: | ||||
|   ansible.builtin.apt_repository: | ||||
|     repo: deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main | ||||
|     mode: 0644 | ||||
|     state: present | ||||
|  | ||||
| - name: Install Java | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: "adoptopenjdk-{{ item.java.version }}-hotspot" | ||||
|     state: present | ||||
|   when: item.java.version is defined | ||||
|   loop: "{{ minecraft }}" | ||||
|  | ||||
| - name: "Install default Java, version {{ minecraft_java }}" | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: "{{ minecraft_java_pkg }}" | ||||
|     state: present | ||||
|   when: item.java.version is not defined | ||||
| @@ -30,7 +30,7 @@ | ||||
|   register: minecraft_java_default | ||||
|  | ||||
| - name: "Activate default Java, version {{ minecraft_java }}" | ||||
|   alternatives: | ||||
|   community.general.alternatives: | ||||
|     name: java | ||||
|     path: "/usr/lib/jvm/{{ minecraft_java_pkg }}-amd64/bin/java" | ||||
|   when: minecraft_java_default.changed | ||||
|   | ||||
| @@ -1,14 +1,14 @@ | ||||
| - import_tasks: system.yml | ||||
| - ansible.builtin.import_tasks: system.yml | ||||
|   when: minecraft_eula | ||||
|  | ||||
| - import_tasks: java.yml | ||||
| - ansible.builtin.import_tasks: java.yml | ||||
|   when: minecraft_eula | ||||
|  | ||||
| - import_tasks: vanilla.yml | ||||
| - ansible.builtin.import_tasks: vanilla.yml | ||||
|   when: minecraft_eula | ||||
|  | ||||
| - import_tasks: modpacks.yml | ||||
| - ansible.builtin.import_tasks: modpacks.yml | ||||
|   when: minecraft_eula | ||||
|  | ||||
| - import_tasks: service.yml | ||||
| - ansible.builtin.import_tasks: service.yml | ||||
|   when: minecraft_eula | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| - name: Download Minecraft modpack installer | ||||
|   get_url: | ||||
|   ansible.builtin.get_url: | ||||
|     url: "{{ minecraft_modpack_url }}" | ||||
|     dest: "{{ minecraft_home }}/{{ item.name }}/serverinstall_{{ item.modpack | replace ('/', '_') }}" | ||||
|     owner: "{{ minecraft_user }}" | ||||
| @@ -9,7 +9,7 @@ | ||||
|   when: item.modpack is defined and item.sha1 is not defined | ||||
|  | ||||
| - name: Run Minecraft modpack installer | ||||
|   command: "sudo -u {{ minecraft_user }} ./serverinstall_{{ item.modpack | replace ('/', '_') }} --auto" | ||||
|   ansible.builtin.command: "sudo -u {{ minecraft_user }} ./serverinstall_{{ item.modpack | replace ('/', '_') }} --auto" | ||||
|   args: | ||||
|     creates: "{{ minecraft_home }}/{{ item.name }}/mods" | ||||
|     chdir: "{{ minecraft_home }}/{{ item.name }}" | ||||
| @@ -17,7 +17,7 @@ | ||||
|   when: item.modpack is defined and item.sha1 is not defined | ||||
|  | ||||
| - name: Find Minecraft Forge | ||||
|   find: | ||||
|   ansible.builtin.find: | ||||
|     paths: "{{ minecraft_home }}/{{ item.name }}" | ||||
|     patterns: "forge*.jar" | ||||
|   register: minecraft_forge | ||||
| @@ -25,7 +25,7 @@ | ||||
|   when: item.modpack is defined and item.sha1 is not defined | ||||
|  | ||||
| - name: Link to Minecraft Forge | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     src: "{{ item.files[0].path }}" | ||||
|     dest: "{{ minecraft_home }}/{{ item.item.name }}/minecraft_server.jar" | ||||
|     owner: "{{ minecraft_user }}" | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| - name: Deploy Minecraft systemd service | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: minecraft.service.j2 | ||||
|     dest: "/etc/systemd/system/minecraft@.service" | ||||
|   register: minecraft_systemd | ||||
|  | ||||
| - name: Deploy service environmental variables | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: environment.conf.j2 | ||||
|     dest: "{{ minecraft_home }}/{{ item.name }}/environment.conf" | ||||
|     owner: "{{ minecraft_user }}" | ||||
| @@ -13,25 +13,25 @@ | ||||
|   loop: "{{ minecraft }}" | ||||
|  | ||||
| - name: Reload systemd manager configuration | ||||
|   systemd: | ||||
|   ansible.builtin.systemd: | ||||
|     daemon_reload: true | ||||
|   when: minecraft_systemd.changed | ||||
|  | ||||
| - name: Disable non-default service instances | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: "minecraft@{{ item.name }}" | ||||
|     enabled: false | ||||
|   loop: "{{ minecraft }}" | ||||
|   when: item.name != minecraft_onboot | ||||
|  | ||||
| - name: Enable default service instance | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: "minecraft@{{ minecraft_onboot }}" | ||||
|     enabled: true | ||||
|   when: minecraft_eula and minecraft_onboot is defined | ||||
|  | ||||
| - name: Run default service instance | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: "minecraft@{{ minecraft_onboot }}" | ||||
|     state: started | ||||
|   when: minecraft_eula and minecraft_onboot is defined and minecraft_onboot_run | ||||
|   | ||||
| @@ -1,16 +1,16 @@ | ||||
| - name: Install Screen | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: screen | ||||
|     state: present | ||||
|  | ||||
| - name: Create Minecraft user | ||||
|   user: | ||||
|   ansible.builtin.user: | ||||
|     name: "{{ minecraft_user }}" | ||||
|     state: present | ||||
|     shell: /bin/bash | ||||
|     ansible.builtin.shell: /bin/bash | ||||
|  | ||||
| - name: Create Minecraft directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ minecraft_home }}/{{ item.name }}" | ||||
|     state: directory | ||||
|     owner: "{{ minecraft_user }}" | ||||
| @@ -18,7 +18,7 @@ | ||||
|   loop: "{{ minecraft }}" | ||||
|  | ||||
| - name: Answer to Mojang's EULA | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: eula.txt.j2 | ||||
|     dest: "{{ minecraft_home }}/{{ item.name }}/eula.txt" | ||||
|     owner: "{{ minecraft_user }}" | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| - name: Download Minecraft | ||||
|   get_url: | ||||
|   ansible.builtin.get_url: | ||||
|     url: "{{ minecraft_url }}" | ||||
|     dest: "{{ minecraft_home }}/{{ item.name }}/minecraft_server.jar" | ||||
|     checksum: "sha1:{{ item.sha1 }}" | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| - name: Create Nextcloud network | ||||
|   docker_network: | ||||
|   community.general.docker_network: | ||||
|     name: "{{ nextcloud_container }}" | ||||
|  | ||||
| - name: Start Nextcloud's database container | ||||
|   docker_container: | ||||
|   community.general.docker_container: | ||||
|     name: "{{ nextcloud_dbcontainer }}" | ||||
|     image: mariadb:{{ nextcloud_dbversion }} | ||||
|     state: started | ||||
| @@ -19,7 +19,7 @@ | ||||
|       MYSQL_PASSWORD: "{{ nextcloud_dbpass }}" | ||||
|  | ||||
| - name: Start Nextcloud container | ||||
|   docker_container: | ||||
|   community.general.docker_container: | ||||
|     name: "{{ nextcloud_container }}" | ||||
|     image: nextcloud:{{ nextcloud_version }} | ||||
|     state: started | ||||
| @@ -41,34 +41,34 @@ | ||||
|       traefik.enable: "true" | ||||
|  | ||||
| - name: Grab Nextcloud database container information | ||||
|   docker_container_info: | ||||
|   community.general.docker_container_info: | ||||
|     name: "{{ nextcloud_dbcontainer }}" | ||||
|   register: nextcloud_dbinfo | ||||
|  | ||||
| - name: Grab Nextcloud container information | ||||
|   docker_container_info: | ||||
|   community.general.docker_container_info: | ||||
|     name: "{{ nextcloud_container }}" | ||||
|   register: nextcloud_info | ||||
|  | ||||
| - name: Wait for Nextcloud to become available | ||||
|   wait_for: | ||||
|   ansible.builtin.wait_for: | ||||
|     host: "{{ nextcloud_info.container.NetworkSettings.Networks.traefik.IPAddress }}" | ||||
|     port: 80 | ||||
|  | ||||
| - name: Check Nextcloud status | ||||
|   command: "docker exec --user www-data {{ nextcloud_container }} | ||||
|   ansible.builtin.command: "docker exec --user www-data {{ nextcloud_container }} | ||||
|             php occ status" | ||||
|   register: nextcloud_status | ||||
|   args: | ||||
|     removes: "{{ nextcloud_root }}/config/CAN_INSTALL" | ||||
|  | ||||
| - name: Wait for Nextcloud database to become available | ||||
|   wait_for: | ||||
|   ansible.builtin.wait_for: | ||||
|     host: "{{ nextcloud_dbinfo.container.NetworkSettings.Networks.nextcloud.IPAddress }}" | ||||
|     port: 3306 | ||||
|  | ||||
| - name: Install Nextcloud | ||||
|   command: 'docker exec --user www-data {{ nextcloud_container }} | ||||
|   ansible.builtin.command: 'docker exec --user www-data {{ nextcloud_container }} | ||||
|             php occ maintenance:install | ||||
|               --database "mysql" | ||||
|               --database-host "{{ nextcloud_dbcontainer }}" | ||||
| @@ -83,19 +83,19 @@ | ||||
|     - nextcloud_domain is defined | ||||
|  | ||||
| - name: Set Nextcloud's Trusted Proxy | ||||
|   command: 'docker exec --user www-data {{ nextcloud_container }} | ||||
|   ansible.builtin.command: 'docker exec --user www-data {{ nextcloud_container }} | ||||
|             php occ config:system:set trusted_proxies 0 | ||||
|               --value="{{ traefik_name }}"' | ||||
|   when: nextcloud_install.changed | ||||
|  | ||||
| - name: Set Nextcloud's Trusted Domain | ||||
|   command: 'docker exec --user www-data {{ nextcloud_container }} | ||||
|   ansible.builtin.command: 'docker exec --user www-data {{ nextcloud_container }} | ||||
|             php occ config:system:set trusted_domains 0 | ||||
|               --value="{{ nextcloud_domain }}"' | ||||
|   when: nextcloud_install.changed | ||||
|  | ||||
| - name: Preform Nextcloud database maintenance | ||||
|   command: "docker exec --user www-data {{ nextcloud_container }} {{ item }}" | ||||
|   ansible.builtin.command: "docker exec --user www-data {{ nextcloud_container }} {{ item }}" | ||||
|   loop: | ||||
|     - "php occ maintenance:mode --on" | ||||
|     - "php occ db:add-missing-indices" | ||||
| @@ -104,6 +104,6 @@ | ||||
|   when: nextcloud_install.changed | ||||
|  | ||||
| - name: Remove Nextcloud's CAN_INSTALL file | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ nextcloud_root }}/config/CAN_INSTALL" | ||||
|     state: absent | ||||
|   | ||||
| @@ -1,15 +1,15 @@ | ||||
| - name: Create nginx root | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ nginx_root }}" | ||||
|     state: directory | ||||
|  | ||||
| - name: Generate deploy keys | ||||
|   openssh_keypair: | ||||
|   community.crypto.openssh_keypair: | ||||
|     path: "{{ nginx_repo_key }}" | ||||
|     state: present | ||||
|  | ||||
| - name: Clone static website files | ||||
|   git: | ||||
|   ansible.builtin.git: | ||||
|     repo: "{{ nginx_repo_url }}" | ||||
|     dest: "{{ nginx_html }}" | ||||
|     version: "{{ nginx_repo_branch }}" | ||||
| @@ -17,7 +17,7 @@ | ||||
|     separate_git_dir: "{{ nginx_repo_dest }}" | ||||
|  | ||||
| - name: Start nginx container | ||||
|   docker_container: | ||||
|   community.general.docker_container: | ||||
|     name: "{{ nginx_name }}" | ||||
|     image: nginx:{{ nginx_version }} | ||||
|     state: started | ||||
| @@ -29,9 +29,9 @@ | ||||
|       - "{{ nginx_html }}:/usr/share/nginx/html:ro" | ||||
|     labels: | ||||
|       traefik.http.routers.nginx.rule: "Host(`{{ nginx_domain }}`)" | ||||
|       traefik.http.middlewares.nginxauth.basicauth.users: "{{ nginx_auth }}" | ||||
|       #traefik.http.middlewares.nginxauth.basicauth.users: "{{ nginx_auth }}" | ||||
|       traefik.http.routers.nginx.entrypoints: websecure | ||||
|       traefik.http.routers.nginx.tls.certresolver: letsencrypt | ||||
|       traefik.http.routers.nginx.middlewares: "securehttps@file,nginxauth" | ||||
|       #traefik.http.routers.nginx.tls.certresolver: letsencrypt | ||||
|       #traefik.http.routers.nginx.middlewares: "securehttps@file,nginxauth" | ||||
|       traefik.docker.network: traefik | ||||
|       traefik.enable: "true" | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| - name: Install PostgreSQL | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: postgresql | ||||
|     state: present | ||||
|  | ||||
| - name: Trust connections to PostgreSQL | ||||
|   postgresql_pg_hba: | ||||
|   community.general.postgresql_pg_hba: | ||||
|     dest: "{{ postgresql_config }}" | ||||
|     contype: host | ||||
|     databases: all | ||||
| @@ -15,7 +15,7 @@ | ||||
|   loop: "{{ postgresql_trust }}" | ||||
|  | ||||
| - name: Change PostgreSQL listen addresses | ||||
|   postgresql_set: | ||||
|   community.general.postgresql_set: | ||||
|     name: listen_addresses | ||||
|     value: "{{ postgresql_listen }}" | ||||
|   become: true | ||||
| @@ -23,19 +23,19 @@ | ||||
|   register: postgresql_config | ||||
|  | ||||
| - name: Reload PostgreSQL | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: postgresql | ||||
|     state: reloaded | ||||
|   when: postgresql_hba.changed and not postgresql_config.changed | ||||
|  | ||||
| - name: Restart PostgreSQL | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: postgresql | ||||
|     state: restarted | ||||
|   when: postgresql_config.changed | ||||
|  | ||||
| - name: Allow database connections | ||||
|   ufw: | ||||
|   community.general.ufw: | ||||
|     rule: allow | ||||
|     port: "5432" | ||||
|     proto: tcp | ||||
|   | ||||
| @@ -1,35 +1,35 @@ | ||||
| - name: Install Prometheus node exporter | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: prometheus-node-exporter | ||||
|     state: present | ||||
|  | ||||
| - name: Run Prometheus node exporter | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: prometheus-node-exporter | ||||
|     state: started | ||||
|  | ||||
| - name: Create Prometheus data directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ prom_root }}/prometheus" | ||||
|     state: directory | ||||
|     owner: nobody | ||||
|  | ||||
| - name: Create Prometheus config directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ prom_root }}/config" | ||||
|     state: directory | ||||
|  | ||||
| - name: Install Prometheus configuration | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: prometheus.yml.j2 | ||||
|     dest: "{{ prom_root }}/config/prometheus.yml" | ||||
|  | ||||
| - name: Create Prometheus network | ||||
|   docker_network: | ||||
|   community.general.docker_network: | ||||
|     name: "{{ prom_name }}" | ||||
|  | ||||
| - name: Start Prometheus container | ||||
|   docker_container: | ||||
|   community.general.docker_container: | ||||
|     name: "{{ prom_name }}" | ||||
|     image: prom/prometheus:{{ prom_version }} | ||||
|     state: started | ||||
| @@ -51,7 +51,7 @@ | ||||
|       traefik.enable: "true" | ||||
|  | ||||
| - name: Start Grafana container | ||||
|   docker_container: | ||||
|   community.general.docker_container: | ||||
|     name: "{{ grafana_name }}" | ||||
|     image: grafana/grafana:{{ grafana_version }} | ||||
|     state: started | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| - name: Reload nginx | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: nginx | ||||
|     state: reloaded | ||||
|   listen: reload_nginx | ||||
|   | ||||
| @@ -1,24 +1,29 @@ | ||||
| - name: Install nginx | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: nginx | ||||
|     state: present | ||||
|     update_cache: true | ||||
|  | ||||
| - name: Start nginx and enable on boot | ||||
|   service: | ||||
|   ansible.builtin.service: | ||||
|     name: nginx | ||||
|     state: started | ||||
|     enabled: true | ||||
|  | ||||
| - name: Generate DH Parameters | ||||
|   community.crypto.openssl_dhparam: | ||||
|     path: /etc/ssl/dhparams.pem | ||||
|     size: 4096 | ||||
|  | ||||
| - name: Install nginx base configuration | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: nginx.conf.j2 | ||||
|     dest: /etc/nginx/nginx.conf | ||||
|     mode: '0644' | ||||
|   notify: reload_nginx | ||||
|  | ||||
| - name: Install nginx sites configuration | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: server-nginx.conf.j2 | ||||
|     dest: "/etc/nginx/sites-available/{{ item.domain }}.conf" | ||||
|     mode: '0644' | ||||
| @@ -27,16 +32,17 @@ | ||||
|   register: nginx_sites | ||||
|  | ||||
| - name: Enable nginx sites configuration | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     src: "/etc/nginx/sites-available/{{ item.item.domain }}.conf" | ||||
|     dest: "/etc/nginx/sites-enabled/{{ item.item.domain }}.conf" | ||||
|     state: link | ||||
|     mode: 0400 | ||||
|   loop: "{{ nginx_sites.results }}" | ||||
|   when: item.changed | ||||
|   notify: reload_nginx | ||||
|  | ||||
| - name: Generate self-signed certificate | ||||
|   shell: 'openssl req -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes \ | ||||
|   ansible.builtin.command: 'openssl req -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes \ | ||||
|           -subj   "/C=US/ST=Local/L=Local/O=Org/OU=IT/CN=example.com" \ | ||||
|           -keyout /etc/ssl/private/nginx-selfsigned.key \ | ||||
|           -out    /etc/ssl/certs/nginx-selfsigned.crt' | ||||
| @@ -46,39 +52,42 @@ | ||||
|   notify: reload_nginx | ||||
|  | ||||
| - name: Install LE's certbot | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: ['certbot', 'python3-certbot-dns-cloudflare'] | ||||
|     state: present | ||||
|   when: proxy.production is defined and proxy.production | ||||
|  | ||||
| - name: Install Cloudflare API token | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: cloudflare.ini.j2 | ||||
|     dest: /root/.cloudflare.ini | ||||
|     mode: '0600' | ||||
|     mode: 0400 | ||||
|   when: proxy.production is defined and proxy.production and proxy.dns_cloudflare is defined | ||||
|  | ||||
| - name: Create nginx post renewal hook directory | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: /etc/letsencrypt/renewal-hooks/post | ||||
|     state: directory | ||||
|     mode: 0500 | ||||
|   when: proxy.production is defined and proxy.production | ||||
|  | ||||
| - name: Install nginx post renewal hook | ||||
|   copy: | ||||
|   ansible.builtin.copy: | ||||
|     src: reload-nginx.sh | ||||
|     dest: /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh | ||||
|     mode: '0755' | ||||
|   when: proxy.production is defined and proxy.production | ||||
|  | ||||
| - name: Run Cloudflare DNS-01 challenges on wildcard domains | ||||
|   shell: '/usr/bin/certbot certonly \ | ||||
|   ansible.builtin.shell: '/usr/bin/certbot certonly \ | ||||
|             --non-interactive \ | ||||
|             --agree-tos \ | ||||
|             --email "{{ proxy.dns_cloudflare.email }}" \ | ||||
|             --dns-cloudflare \ | ||||
|             --dns-cloudflare-credentials /root/.cloudflare.ini \ | ||||
|             -d "*.{{ item }}" {{ proxy.dns_cloudflare.opts | default("") }}' | ||||
|             -d "*.{{ item }}" \ | ||||
|             -d "{{ item }}" \ | ||||
|             {{ proxy.dns_cloudflare.opts | default("") }}' | ||||
|   args: | ||||
|     creates: "/etc/letsencrypt/live/{{ item }}/fullchain.pem" | ||||
|   loop: "{{ proxy.dns_cloudflare.wildcard_domains }}" | ||||
| @@ -86,7 +95,7 @@ | ||||
|   notify: reload_nginx | ||||
|  | ||||
| - name: Add HTTP and HTTPS firewall rule | ||||
|   ufw: | ||||
|   community.general.ufw: | ||||
|     rule: allow | ||||
|     port: "{{ item }}" | ||||
|     proto: tcp | ||||
|   | ||||
| @@ -21,6 +21,14 @@ http { | ||||
|   keepalive_timeout 65; | ||||
|   server_names_hash_bucket_size 128; | ||||
|  | ||||
|   ssl_protocols TLSv1.2 TLSv1.3; | ||||
|   ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; | ||||
|   ssl_prefer_server_ciphers off; | ||||
|   ssl_dhparam /etc/ssl/dhparams.pem; | ||||
|   ssl_session_cache shared:SSL:10m; | ||||
|   ssl_session_timeout 1d; | ||||
|   ssl_session_tickets off; | ||||
|  | ||||
|   include           /etc/nginx/conf.d/*.conf; | ||||
|   include           /etc/nginx/sites-enabled/*; | ||||
| } | ||||
|   | ||||
| @@ -1,12 +1,13 @@ | ||||
| server { | ||||
|     listen 80; | ||||
|  | ||||
|     server_name {{ item.domain }}; | ||||
|     return 301 https://{{ item.domain }}$request_uri; | ||||
|   listen 80; | ||||
|   listen [::]:80; | ||||
|   server_name {{ item.domain }}; | ||||
|   return 301 https://{{ item.domain }}$request_uri; | ||||
| } | ||||
|  | ||||
| server { | ||||
|   listen              443 ssl; | ||||
|   listen              443      ssl http2; | ||||
|   listen              [::]:443 ssl http2; | ||||
|   server_name         {{ item.domain }}; | ||||
|   access_log          /var/log/nginx/{{ item.domain }}.log main; | ||||
| {% if proxy.production is defined and proxy.production and proxy.dns_cloudflare.wildcard_domains is defined and item.tls.cert is not defined %} | ||||
| @@ -26,11 +27,18 @@ server { | ||||
| {% else %} | ||||
|   ssl_certificate     /etc/ssl/certs/nginx-selfsigned.crt; | ||||
|   ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key; | ||||
| {% endif %} | ||||
| {% if item.hsts is defined %} | ||||
|   add_header Strict-Transport-Security "max-age={{ item.hsts }}" always; | ||||
| {% endif %} | ||||
| {% if item.client_max_body_size is defined %} | ||||
|   client_max_body_size {{ item.client_max_body_size }}; | ||||
| {% endif %} | ||||
|   location / { | ||||
| {% if item.restrict is defined and item.restrict  %} | ||||
|     auth_basic "{{ item.restrict_name | default('Restricted Access') }}"; | ||||
|     auth_basic_user_file {{ item.restrict_file | default('/etc/nginx/.htpasswd') }}; | ||||
|     proxy_set_header Authorization ""; | ||||
| {% endif %} | ||||
|     proxy_set_header Host $host; | ||||
|     proxy_set_header X-Real-IP $remote_addr; | ||||
| @@ -38,6 +46,12 @@ server { | ||||
|     proxy_pass {{ item.proxy_pass }}; | ||||
| {% if item.proxy_ssl_verify is defined and item.proxy_ssl_verify is false %} | ||||
|     proxy_ssl_verify off; | ||||
| {% endif %} | ||||
| {% if item.websockets is defined and item.websockets %} | ||||
|     proxy_http_version 1.1; | ||||
|     proxy_set_header Connection $http_connection; | ||||
|     proxy_set_header Origin http://$host; | ||||
|     proxy_set_header Upgrade $http_upgrade; | ||||
| {% endif %} | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -13,12 +13,12 @@ | ||||
| # along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
|  | ||||
| - name: Install rsnapshot | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: rsnapshot | ||||
|     state: present | ||||
|  | ||||
| - name: Create rsnapshot system directories | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ item }}" | ||||
|     state: directory | ||||
|   loop: | ||||
| @@ -26,19 +26,19 @@ | ||||
|     - "{{ rsnapshot_logdir }}" | ||||
|  | ||||
| - name: Create snapshot_root directories | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ item.root | default(rsnapshot_root) }}" | ||||
|     state: directory | ||||
|   loop: "{{ rsnapshot }}" | ||||
|  | ||||
| - name: Install rsnapshot configuration | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: rsnapshot.conf.j2 | ||||
|     dest: "{{ rsnapshot_confdir }}/{{ item.name }}.conf" | ||||
|   loop: "{{ rsnapshot }}" | ||||
|  | ||||
| - name: Install rsnapshot crons | ||||
|   cron: | ||||
|   ansible.builtin.cron: | ||||
|     name: "{{ item.1.interval }} rsnapshot of {{ item.0.name }}" | ||||
|     job: "/usr/bin/rsnapshot -c {{ rsnapshot_confdir }}/{{ item.0.name }}.conf {{ item.1.interval }} >/dev/null" | ||||
|     user: "root" | ||||
| @@ -53,13 +53,13 @@ | ||||
|     - cron | ||||
|  | ||||
| - name: Install rsnapshot report script | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: rsnapshot-report.sh.j2 | ||||
|     dest: /usr/local/bin/rsnapshot-report | ||||
|     mode: '0750' | ||||
|  | ||||
| - name: Install rsnapshot report crons | ||||
|   cron: | ||||
|   ansible.builtin.cron: | ||||
|     name: "{{ item.name }} rsnapshot report email" | ||||
|     job: "/usr/local/bin/rsnapshot-report {{ rsnapshot_reportlog }} | ||||
|           | mail -s '{{ item.report.subject | default('Backup Report') }}' {{ item.report.to }}" | ||||
|   | ||||
| @@ -1,10 +1,18 @@ | ||||
| # Container settings | ||||
| traefik_name: traefik | ||||
| traefik_dashboard: false | ||||
| traefik_root: "/opt/{{ traefik_name }}" | ||||
| traefik_standalone: true | ||||
| traefik_http_only: false | ||||
| traefik_debug: false | ||||
| traefik_web_entry: "127.0.0.1:8000" | ||||
| traefik_websecure_entry: "127.0.0.1:8443" | ||||
| traefik_localonly: "10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8" | ||||
|  | ||||
| # HTTPS settings | ||||
| traefik_production: false | ||||
| traefik_hsts_enable: false | ||||
| traefik_hsts_preload: false | ||||
| traefik_hsts_seconds: 0 | ||||
| traefik_ports: | ||||
|   - "80:80" | ||||
|   - "443:443" | ||||
| traefik_http_redirect: true | ||||
|  | ||||
| # Host settings | ||||
| traefik_root: "{{ docker_compose_root }}/{{ traefik_name }}" | ||||
|   | ||||
| @@ -1,14 +1,12 @@ | ||||
| - name: Reload Traefik container | ||||
|   file: | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ traefik_root }}/config/dynamic" | ||||
|     state: touch | ||||
|     mode: 0500 | ||||
|   listen: reload_traefik | ||||
|  | ||||
| - name: Restart Traefik container | ||||
|   docker_container: | ||||
|     name: "{{ traefik_name }}" | ||||
|     image: traefik:{{ traefik_version }} | ||||
|     state: started | ||||
|     container_default_behavior: "no_defaults" | ||||
|     restart: yes | ||||
| - name: Restart Traefik | ||||
|   ansible.builtin.service: | ||||
|     name: "{{ docker_compose_service }}@{{ traefik_name }}" | ||||
|     state: restarted | ||||
|   listen: restart_traefik | ||||
|   | ||||
| @@ -1,56 +1,49 @@ | ||||
| - name: Create Traefik configuration directories | ||||
|   file: | ||||
| - name: Create Traefik directories | ||||
|   ansible.builtin.file: | ||||
|     path: "{{ traefik_root }}/config/dynamic" | ||||
|     mode: 0500 | ||||
|     state: directory | ||||
|  | ||||
| - name: Install static Traefik configuration | ||||
|   template: | ||||
|     src: traefik.yml.j2 | ||||
|     dest: "{{ traefik_root }}/config/traefik.yml" | ||||
|   notify: restart_traefik | ||||
|  | ||||
| - name: Install dynamic security configuration | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: security.yml.j2 | ||||
|     dest: "{{ traefik_root }}/config/dynamic/security.yml" | ||||
|     owner: root | ||||
|     group: root | ||||
|     mode: 0600 | ||||
|     mode: 0400 | ||||
|   notify: reload_traefik | ||||
|  | ||||
| - name: Install dynamic non-docker configuration | ||||
|   template: | ||||
|   ansible.builtin.template: | ||||
|     src: "external.yml.j2" | ||||
|     dest: "{{ traefik_root }}/config/dynamic/{{ item.name }}.yml" | ||||
|     mode: 0400 | ||||
|   loop: "{{ traefik_external }}" | ||||
|   when: traefik_external is defined | ||||
|  | ||||
| - name: Create Traefik network | ||||
|   docker_network: | ||||
|     name: traefik | ||||
| - name: Install Traefik's docker-compose file | ||||
|   ansible.builtin.template: | ||||
|     src: docker-compose.yml.j2 | ||||
|     dest: "{{ traefik_root }}/docker-compose.yml" | ||||
|     mode: 0400 | ||||
|   notify: restart_traefik | ||||
|  | ||||
| - name: Start Traefik container | ||||
|   docker_container: | ||||
|     name: "{{ traefik_name }}" | ||||
|     image: traefik:{{ traefik_version }} | ||||
| - name: Install Traefik's docker-compose variables | ||||
|   ansible.builtin.template: | ||||
|     src: compose-env.j2 | ||||
|     dest: "{{ traefik_root }}/.env" | ||||
|     mode: 0400 | ||||
|   notify: restart_traefik | ||||
|  | ||||
| - name: Install static Traefik configuration | ||||
|   ansible.builtin.template: | ||||
|     src: traefik.yml.j2 | ||||
|     dest: "{{ traefik_root }}/config/traefik.yml" | ||||
|     mode: 0400 | ||||
|   notify: restart_traefik | ||||
|  | ||||
| - name: Start and enable Traefik service | ||||
|   ansible.builtin.service: | ||||
|     name: "{{ docker_compose_service }}@{{ traefik_name }}" | ||||
|     state: started | ||||
|     restart_policy: always | ||||
|     ports: "{{ traefik_ports }}" | ||||
|     container_default_behavior: "no_defaults" | ||||
|     networks_cli_compatible: "false" | ||||
|     networks: | ||||
|       - name: traefik | ||||
|     labels: | ||||
|       traefik.http.routers.traefik.rule: "Host(`{{ traefik_domain }}`)" | ||||
|       traefik.http.middlewares.auth.basicauth.users: "{{ traefik_auth }}" | ||||
|       traefik.http.middlewares.localonly.ipwhitelist.sourcerange: "{{ traefik_localonly }}" | ||||
|       traefik.http.routers.traefik.tls.certresolver: letsencrypt | ||||
|       traefik.http.routers.traefik.middlewares: "securehttps@file,auth@docker,localonly" | ||||
|       traefik.http.routers.traefik.service: "api@internal" | ||||
|       traefik.http.routers.traefik.entrypoints: websecure | ||||
|       traefik.http.routers.traefik.tls: "true" | ||||
|       traefik.docker.network: traefik | ||||
|       traefik.enable: "{{ traefik_dashboard | string }}" | ||||
|     volumes: | ||||
|       - /var/run/docker.sock:/var/run/docker.sock | ||||
|       - "{{ traefik_root }}/config:/etc/traefik" | ||||
|     enabled: true | ||||
|   | ||||
							
								
								
									
										8
									
								
								roles/traefik/templates/compose-env.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								roles/traefik/templates/compose-env.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| # {{ ansible_managed }} | ||||
| traefik_version={{ traefik_version }} | ||||
| traefik_name={{ traefik_name }} | ||||
| traefik_domain={{ traefik_domain }} | ||||
| traefik_dashboard={{ traefik_dashboard | string | lower }} | ||||
| traefik_debug={{ traefik_debug | string | lower }} | ||||
| traefik_web_entry={{ traefik_web_entry }} | ||||
| traefik_websecure_entry={{ traefik_websecure_entry }} | ||||
							
								
								
									
										25
									
								
								roles/traefik/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								roles/traefik/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| version: '3.7' | ||||
|  | ||||
| networks: | ||||
|   traefik: | ||||
|     name: traefik | ||||
|  | ||||
| services: | ||||
|   traefik: | ||||
|     image: "traefik:${traefik_version}" | ||||
|     container_name: "${traefik_name}" | ||||
|     ports: | ||||
|       - "${traefik_web_entry}:80" | ||||
| {% if traefik_standalone and not traefik_http_only %} | ||||
|       - "${traefik_websecure_entry}:443" | ||||
| {% endif %} | ||||
|     networks: | ||||
|       - traefik | ||||
|     labels: | ||||
|       - "traefik.http.routers.traefik.rule=Host(`{{ traefik_domain }}`)" | ||||
|       - "traefik.http.routers.traefik.service=api@internal" | ||||
|       - "traefik.docker.network=traefik" | ||||
|       - "traefik.enable=${traefik_dashboard}" | ||||
|     volumes: | ||||
|       - /var/run/docker.sock:/var/run/docker.sock | ||||
|       - "{{ traefik_root }}/config:/etc/traefik" | ||||
| @@ -10,10 +10,12 @@ http: | ||||
| {% elif item.middlewares is defined %} | ||||
|       middlewares: "{{ item.middlewares }}" | ||||
| {% endif %} | ||||
| {% if traefik_acme_email is defined %} | ||||
|       tls: | ||||
|         certResolver: letsencrypt | ||||
|         domains: | ||||
|           - main: "{{ item.domain }}" | ||||
| {% endif %} | ||||
|       entryPoints: | ||||
|         - "websecure" | ||||
|   services: | ||||
|   | ||||
| @@ -11,6 +11,8 @@ http: | ||||
|         sslRedirect: true | ||||
|         browserXssFilter: true | ||||
|         contentTypeNosniff: true | ||||
| {% if traefik_hsts_enable is defined and traefik_hsts_enable %} | ||||
|         stsPreload: {{ traefik_hsts_preload }} | ||||
|         stsSeconds: {{ traefik_hsts_seconds }} | ||||
| {% endif %} | ||||
|         customFrameOptionsValue: SAMEORIGIN | ||||
|   | ||||
| @@ -10,16 +10,20 @@ providers: | ||||
| entrypoints: | ||||
|   web: | ||||
|     address: ':80' | ||||
| {% if traefik_http_redirect is defined and traefik_http_redirect and not traefik_http_only %} | ||||
|     http: | ||||
|       redirections: | ||||
|         entrypoint: | ||||
|           to: websecure | ||||
|           scheme: https | ||||
|           permanent: true | ||||
| {% endif %} | ||||
| {% if not traefik_http_only is defined or not traefik_http_only %} | ||||
|   websecure: | ||||
|     address: ':443' | ||||
|     http: | ||||
|       tls: {} | ||||
| {% endif %} | ||||
|  | ||||
| {% if traefik_acme_email is defined %} | ||||
| certificatesResolvers: | ||||
|   | ||||
| @@ -1,52 +1,52 @@ | ||||
| - name: Install GnuPG | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: gnupg | ||||
|     state: present | ||||
|  | ||||
| - name: Add AdoptOpenJDK's signing key | ||||
|   apt_key: | ||||
|   ansible.builtin.apt_key: | ||||
|     id: 8ED17AF5D7E675EB3EE3BCE98AC3B29174885C03 | ||||
|     url: https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | ||||
|  | ||||
| - name: Add MongoDB 3.6's signing key | ||||
|   apt_key: | ||||
|   ansible.builtin.apt_key: | ||||
|     id: 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5 | ||||
|     url: https://www.mongodb.org/static/pgp/server-3.6.asc | ||||
|  | ||||
| - name: Add UniFi's signing key | ||||
|   apt_key: | ||||
|   ansible.builtin.apt_key: | ||||
|     id: 4A228B2D358A5094178285BE06E85760C0A52C50 | ||||
|     keyserver: keyserver.ubuntu.com | ||||
|  | ||||
| - name: Install AdoptOpenJDK repository | ||||
|   apt_repository: | ||||
|   ansible.builtin.apt_repository: | ||||
|     repo: deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main | ||||
|     mode: 0644 | ||||
|     state: present | ||||
|  | ||||
| - name: Install MongoDB 3.6 repository | ||||
|   apt_repository: | ||||
|   ansible.builtin.apt_repository: | ||||
|     repo: deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/3.6 main | ||||
|     mode: 0644 | ||||
|     state: present | ||||
|  | ||||
| - name: Install UniFi repository | ||||
|   apt_repository: | ||||
|   ansible.builtin.apt_repository: | ||||
|     repo: deb https://www.ui.com/downloads/unifi/debian stable ubiquiti | ||||
|     mode: 0644 | ||||
|     state: present | ||||
|  | ||||
| - name: Install MongoDB 3.6 | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: mongodb-org | ||||
|     state: present | ||||
|  | ||||
| - name: Install OpenJDK 8 LTS | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: adoptopenjdk-8-hotspot | ||||
|     state: present | ||||
|  | ||||
| - name: Install UniFi | ||||
|   apt: | ||||
|   ansible.builtin.apt: | ||||
|     name: unifi | ||||
|     state: present | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| - name: Start WordPress database container | ||||
|   docker_container: | ||||
|   community.general.docker_container: | ||||
|     name: "{{ wordpress_dbcontainer }}" | ||||
|     image: mariadb:{{ wordpress_dbversion }} | ||||
|     restart_policy: always | ||||
| @@ -11,7 +11,7 @@ | ||||
|       MYSQL_PASSWORD: "{{ wordpress_dbpass }}" | ||||
|  | ||||
| - name: Start WordPress container | ||||
|   docker_container: | ||||
|   community.general.docker_container: | ||||
|     name: "{{ wordpress_container }}" | ||||
|     image: wordpress:{{ wordpress_version }} | ||||
|     restart_policy: always | ||||
|   | ||||
| @@ -14,6 +14,7 @@ HOST[8]="wordpress.${DOMAIN}" | ||||
| HOST[9]="site1.wordpress.${DOMAIN}" | ||||
| HOST[10]="site2.wordpress.${DOMAIN}" | ||||
| HOST[11]="unifi.${DOMAIN}" | ||||
| HOST[12]="jellyfin.${DOMAIN}" | ||||
|  | ||||
| # Get Vagrantbox guest IP | ||||
| VAGRANT_OUTPUT=$(vagrant ssh -c "hostname -I | cut -d' ' -f2" 2>/dev/null) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user