Compare commits
	
		
			49 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f4f5b10395 | |||
| 9b5be29a1a | |||
| ef5aacdbbd | |||
| a635c7aa48 | |||
| 56aee460ad | |||
| 027ba46f6b | |||
| 48216db8f9 | |||
| fa1dc4acb7 | |||
| 228cd5795b | |||
| 74a559f1f6 | |||
| 4c2a1550c4 | |||
| f02cf7b0cc | |||
| 9142254a57 | |||
| dfd93dd5f8 | |||
| 81d2ea447a | |||
| 9512212b84 | |||
| c67a39982e | |||
| f68f57d0cf | |||
| b9f9b0bf3c | |||
| 4f4a341b05 | |||
| cab6ab2d8e | |||
| 95f54b7f0a | |||
| 7522c333da | |||
| 344b79e97f | |||
| e4fed78193 | |||
| 85a6c3894a | |||
| 7677bc25fa | |||
| b255680a7a | |||
| 9eefad0e87 | |||
| 8362230eb4 | |||
| 82df91305a | |||
| dd9f84d498 | |||
| b52ccabd22 | |||
| eccd6b7874 | |||
| 3a92921932 | |||
| 330f2b5a91 | |||
| 45465ad26b | |||
| d7838563a1 | |||
| 03a57d2531 | |||
| e346180b13 | |||
| be6e1596c5 | |||
| dc520a09e9 | |||
| c0be314268 | |||
| 9aca035f2d | |||
| 209ff57a4a | |||
| 9a4aece442 | |||
| acd2cefb1e | |||
| cd11567164 | |||
| 1c321f6ef7 | 
							
								
								
									
										39
									
								
								.github/workflows/vagrant.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								.github/workflows/vagrant.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | name: homelab-ci | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - main | ||||||
|  |       - testing | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   homelab-ci: | ||||||
|  |     runs-on: macos-latest | ||||||
|  |  | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |       - name: Cache Vagrant boxes | ||||||
|  |         uses: actions/cache@v3 | ||||||
|  |         with: | ||||||
|  |           path: ~/.vagrant.d/boxes | ||||||
|  |           key: ${{ runner.os }}-vagrant-${{ hashFiles('Vagrantfile') }} | ||||||
|  |           restore-keys: | | ||||||
|  |             ${{ runner.os }}-vagrant- | ||||||
|  |  | ||||||
|  |       - name: Install Ansible | ||||||
|  |         run: brew install ansible@7 | ||||||
|  |  | ||||||
|  |       - name: Software Versions | ||||||
|  |         run: | | ||||||
|  |           printf "VirtualBox " | ||||||
|  |           vboxmanage --version | ||||||
|  |           vagrant --version | ||||||
|  |           export PATH="/usr/local/opt/ansible@7/bin:$PATH" | ||||||
|  |           ansible --version | ||||||
|  |  | ||||||
|  |       - name: Vagrant Up with Dockerbox Playbook | ||||||
|  |         run: | | ||||||
|  |           export PATH="/usr/local/opt/ansible@7/bin:$PATH" | ||||||
|  |           PLAYBOOK=dockerbox vagrant up | ||||||
|  |           vagrant ssh -c "docker ps" | ||||||
							
								
								
									
										14
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,12 +1,4 @@ | |||||||
| .vagrant |  | ||||||
| .playbook | .playbook | ||||||
| /*.yml | .vagrant* | ||||||
| /*.yaml | .vscode | ||||||
| !backup.yml | /environments/ | ||||||
| !moxie.yml |  | ||||||
| !docker.yml |  | ||||||
| !dockerbox.yml |  | ||||||
| !hypervisor.yml |  | ||||||
| !minecraft.yml |  | ||||||
| !unifi.yml |  | ||||||
| /environments/ |  | ||||||
							
								
								
									
										46
									
								
								Vagrantfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								Vagrantfile
									
									
									
									
										vendored
									
									
								
							| @@ -1,42 +1,45 @@ | |||||||
| # -*- mode: ruby -*- | # -*- mode: ruby -*- | ||||||
| # vi: set ft=ruby : | # vi: set ft=ruby : | ||||||
|  |  | ||||||
| SSH_FORWARD=ENV["SSH_FORWARD"] | require 'yaml' | ||||||
| if !(SSH_FORWARD == "true") | settings_path = '.vagrant.yml' | ||||||
|   SSH_FORWARD = false | settings = {} | ||||||
|  |  | ||||||
|  | if File.exist?(settings_path) | ||||||
|  |   settings = YAML.load_file(settings_path) | ||||||
| end | end | ||||||
|  |  | ||||||
|  | VAGRANT_BOX  = settings['VAGRANT_BOX']  || 'debian/bookworm64' | ||||||
|  | VAGRANT_CPUS = settings['VAGRANT_CPUS'] || 2 | ||||||
|  | VAGRANT_MEM  = settings['VAGRANT_MEM']  || 2048 | ||||||
|  | SSH_FORWARD  = settings['SSH_FORWARD']  || false | ||||||
|  |  | ||||||
|  | # Default to shell environment variable: PLAYBOOK (priority #1) | ||||||
| PLAYBOOK=ENV["PLAYBOOK"] | PLAYBOOK=ENV["PLAYBOOK"] | ||||||
| if !PLAYBOOK | if !PLAYBOOK | ||||||
|   if File.exist?('.playbook') |   # PLAYBOOK setting in .vagrant.yml (priority #2) | ||||||
|     PLAYBOOK = IO.read('.playbook').split("\n")[0] |   PLAYBOOK = settings['PLAYBOOK'] || false | ||||||
|   end |  | ||||||
|  |  | ||||||
|   if !PLAYBOOK || PLAYBOOK.empty? |   if !PLAYBOOK || PLAYBOOK.empty? | ||||||
|     PLAYBOOK = "\nERROR: Set env PLAYBOOK" |     puts "[VAGRANTFILE ERROR]: Set PLAYBOOK setting in .vagrant.yml" | ||||||
|  |     abort | ||||||
|   end |   end | ||||||
| else |  | ||||||
|   File.write(".playbook", PLAYBOOK) |  | ||||||
| end | end | ||||||
|  |  | ||||||
| Vagrant.configure("2") do |config| | Vagrant.configure("2") do |config| | ||||||
|   config.vm.box = "debian/bullseye64" |   config.vm.box = VAGRANT_BOX | ||||||
|   config.vm.network "private_network", type: "dhcp" |   config.vm.network "private_network", type: "dhcp" | ||||||
|   config.vm.synced_folder ".", "/vagrant", disabled: true |  | ||||||
|   config.vm.synced_folder "./scratch", "/vagrant/scratch" |  | ||||||
|   config.ssh.forward_agent = SSH_FORWARD |   config.ssh.forward_agent = SSH_FORWARD | ||||||
|  |  | ||||||
|   # Machine Name |   # Libvrit provider | ||||||
|   config.vm.define :moxie do |moxie| # |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   # Disable Machine Name Prefix |  | ||||||
|   config.vm.provider :libvirt do |libvirt| |   config.vm.provider :libvirt do |libvirt| | ||||||
|     libvirt.default_prefix = "" |     libvirt.cpus   = VAGRANT_CPUS | ||||||
|  |     libvirt.memory = VAGRANT_MEM | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   config.vm.provider "virtualbox" do |vbox| |   # Virtualbox provider | ||||||
|     vbox.memory = 4096 |   config.vm.provider :virtualbox do |vbox| | ||||||
|  |     vbox.cpus   = VAGRANT_CPUS | ||||||
|  |     vbox.memory = VAGRANT_MEM | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   # Provision with Ansible |   # Provision with Ansible | ||||||
| @@ -45,5 +48,4 @@ Vagrant.configure("2") do |config| | |||||||
|     ansible.compatibility_mode = "2.0" |     ansible.compatibility_mode = "2.0" | ||||||
|     ansible.playbook = "dev/" + PLAYBOOK + ".yml" |     ansible.playbook = "dev/" + PLAYBOOK + ".yml" | ||||||
|   end |   end | ||||||
|  |  | ||||||
| end | end | ||||||
|   | |||||||
| @@ -1,3 +1,6 @@ | |||||||
| [defaults] | [defaults] | ||||||
| inventory = ./environments/development | inventory = ./environments/development | ||||||
| interpreter_python = /usr/bin/python3 | interpreter_python = /usr/bin/python3 | ||||||
|  |  | ||||||
|  | [connection] | ||||||
|  | pipelining = true | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ | |||||||
|     - docker |     - docker | ||||||
|     - traefik |     - traefik | ||||||
|     - nextcloud |     - nextcloud | ||||||
|     - gitea |  | ||||||
|     - jenkins |     - jenkins | ||||||
|     - prometheus |     - prometheus | ||||||
|     - nginx |     - nginx | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ traefik_domain: traefik.vm.krislamo.org | |||||||
| traefik_auth: admin:$apr1$T1l.BCFz$Jyg8msXYEAUi3LLH39I9d1 # admin:admin | traefik_auth: admin:$apr1$T1l.BCFz$Jyg8msXYEAUi3LLH39I9d1 # admin:admin | ||||||
| #traefik_acme_email: realemail@example.com # Let's Encrypt settings | #traefik_acme_email: realemail@example.com # Let's Encrypt settings | ||||||
| #traefik_production: true | #traefik_production: true | ||||||
|  | traefik_http_only: true # if behind reverse-proxy | ||||||
|  |  | ||||||
| # nextcloud | # nextcloud | ||||||
| nextcloud_version: stable | nextcloud_version: stable | ||||||
|   | |||||||
| @@ -1,27 +0,0 @@ | |||||||
| # base |  | ||||||
| allow_reboot: false |  | ||||||
| manage_network: false |  | ||||||
|  |  | ||||||
| # docker |  | ||||||
| docker_users: |  | ||||||
|   - vagrant |  | ||||||
|  |  | ||||||
| # traefik |  | ||||||
| traefik_version: latest |  | ||||||
| traefik_dashboard: true |  | ||||||
| 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 |  | ||||||
|  |  | ||||||
| # jekyll |  | ||||||
| jekyll_project: example |  | ||||||
| jekyll_repo_url: https://git.krislamo.org/kris/example-jekyll/ |  | ||||||
| jekyll_repo_branch: master |  | ||||||
|  |  | ||||||
| # nginx |  | ||||||
| nginx_domain: nginx.vm.krislamo.org |  | ||||||
| nginx_name: staticsite |  | ||||||
| nginx_repo_url: https://git.krislamo.org/kris/example-website/ |  | ||||||
| nginx_auth: admin:$apr1$T1l.BCFz$Jyg8msXYEAUi3LLH39I9d1 # admin:admin |  | ||||||
| nginx_version: latest |  | ||||||
							
								
								
									
										56
									
								
								dev/host_vars/mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								dev/host_vars/mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | base_domain: vm.krislamo.org | ||||||
|  |  | ||||||
|  | # base | ||||||
|  | allow_reboot: false | ||||||
|  | manage_network: false | ||||||
|  |  | ||||||
|  | users: | ||||||
|  |   - name: jellyfin | ||||||
|  |  | ||||||
|  | samba: | ||||||
|  |   users: | ||||||
|  |     - name: jellyfin | ||||||
|  |       password: jellyfin | ||||||
|  |   shares: | ||||||
|  |     - name: jellyfin | ||||||
|  |       path: /srv/jellyfin | ||||||
|  |       owner: jellyfin | ||||||
|  |       group: jellyfin | ||||||
|  |       valid_users: jellyfin | ||||||
|  |   firewall: | ||||||
|  |     - 10.0.0.0/8 | ||||||
|  |     - 172.16.0.0/12 | ||||||
|  |     - 192.168.0.0/16 | ||||||
|  |  | ||||||
|  | # 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 | ||||||
|  | jellyfin_media: /srv/jellyfin | ||||||
							
								
								
									
										37
									
								
								dev/host_vars/proxy.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								dev/host_vars/proxy.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: "{{ bitwarden_domain }}" | ||||||
|  |       proxy_pass: "http://127.0.0.1:8080" | ||||||
|  |     - domain: "{{ gitea_domain }}" | ||||||
|  |       proxy_pass: "http://127.0.0.1:3000" | ||||||
|  |  | ||||||
|  | # docker | ||||||
|  | docker_users: | ||||||
|  |   - vagrant | ||||||
|  |  | ||||||
|  | # bitwarden | ||||||
|  | # Get Installation ID & Key at https://bitwarden.com/host/ | ||||||
|  | bitwarden_domain: "vault.{{ base_domain }}" | ||||||
|  | bitwarden_dbpass: password | ||||||
|  | bitwarden_install_id: 4ea840a3-532e-4cb6-a472-abd900728b23 | ||||||
|  | bitwarden_install_key: 1yB3Z2gRI0KnnH90C6p | ||||||
|  | #bitwarden_prodution: true | ||||||
|  |  | ||||||
|  | # gitea | ||||||
|  | gitea_domain: "git.{{ base_domain }}" | ||||||
|  | gitea_version: 1 | ||||||
|  | gitea_dbpass: password | ||||||
| @@ -14,7 +14,7 @@ traefik_auth: admin:$apr1$T1l.BCFz$Jyg8msXYEAUi3LLH39I9d1 # admin:admin | |||||||
| #traefik_acme_email: realemail@example.com # Let's Encrypt settings | #traefik_acme_email: realemail@example.com # Let's Encrypt settings | ||||||
| #traefik_production: true | #traefik_production: true | ||||||
| 
 | 
 | ||||||
| # nginx | # staticweb | ||||||
| nginx_domain: nginx.vm.krislamo.org | nginx_domain: nginx.vm.krislamo.org | ||||||
| nginx_name: staticsite | nginx_name: staticsite | ||||||
| nginx_repo_url: https://git.krislamo.org/kris/example-website/ | nginx_repo_url: https://git.krislamo.org/kris/example-website/ | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| - name: Install Jekyll server |  | ||||||
|   hosts: all |  | ||||||
|   become: true |  | ||||||
|   vars_files: |  | ||||||
|     - host_vars/jekyll.yml |  | ||||||
|   roles: |  | ||||||
|     - base |  | ||||||
|     - docker |  | ||||||
|     #- traefik |  | ||||||
|     - jekyll |  | ||||||
|     #- nginx |  | ||||||
							
								
								
									
										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 | ||||||
							
								
								
									
										12
									
								
								dev/proxy.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								dev/proxy.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | - name: Install Proxy Server | ||||||
|  |   hosts: all | ||||||
|  |   become: true | ||||||
|  |   vars_files: | ||||||
|  |     - host_vars/proxy.yml | ||||||
|  |   roles: | ||||||
|  |     - base | ||||||
|  |     - mariadb | ||||||
|  |     - proxy | ||||||
|  |     - docker | ||||||
|  |     - gitea | ||||||
|  |     - bitwarden | ||||||
| @@ -1,10 +1,10 @@ | |||||||
| - name: Install nginx server (docker) | - name: Install a static web container | ||||||
|   hosts: all |   hosts: all | ||||||
|   become: true |   become: true | ||||||
|   vars_files: |   vars_files: | ||||||
|     - host_vars/nginx.yml |     - host_vars/staticweb.yml | ||||||
|   roles: |   roles: | ||||||
|     - base |     - base | ||||||
|     - docker |     - docker | ||||||
|     - traefik |     - traefik | ||||||
|     - nginx |     - staticweb | ||||||
							
								
								
									
										18
									
								
								docker.yml
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								docker.yml
									
									
									
									
									
								
							| @@ -1,21 +1,7 @@ | |||||||
| # Copyright (C) 2020  Kris Lamoureux |  | ||||||
| # |  | ||||||
| # This program is free software: you can redistribute it and/or modify |  | ||||||
| # it under the terms of the GNU General Public License as published by |  | ||||||
| # the Free Software Foundation, version 3 of the License. |  | ||||||
| # |  | ||||||
| # This program is distributed in the hope that it will be useful, |  | ||||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| # GNU General Public License for more details. |  | ||||||
| # |  | ||||||
| # You should have received a copy of the GNU General Public License |  | ||||||
| # along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  |  | ||||||
| - name: Install Docker Server | - name: Install Docker Server | ||||||
|   hosts: dockerhosts |   hosts: "{{ PLAYBOOK_HOST | default('none') }}" | ||||||
|   become: true |   become: true | ||||||
|   roles: |   roles: | ||||||
|     - base |     - base | ||||||
|     - docker |  | ||||||
|     - jenkins |     - jenkins | ||||||
|  |     - docker | ||||||
|   | |||||||
| @@ -20,7 +20,6 @@ | |||||||
|     - docker |     - docker | ||||||
|     - traefik |     - traefik | ||||||
|     - nextcloud |     - nextcloud | ||||||
|     - gitea |  | ||||||
|     - jenkins |     - jenkins | ||||||
|     - prometheus |     - prometheus | ||||||
|     - nginx |     - nginx | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								mediaserver.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | - name: Install Media Server | ||||||
|  |   hosts: "{{ PLAYBOOK_HOST | default('none') }}" | ||||||
|  |   become: true | ||||||
|  |   roles: | ||||||
|  |     - base | ||||||
|  |     - jenkins | ||||||
|  |     - proxy | ||||||
|  |     - docker | ||||||
|  |     - traefik | ||||||
|  |     - jellyfin | ||||||
							
								
								
									
										11
									
								
								proxy.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								proxy.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | - name: Install Proxy Server | ||||||
|  |   hosts: proxyhosts | ||||||
|  |   become: true | ||||||
|  |   roles: | ||||||
|  |     - base | ||||||
|  |     - jenkins | ||||||
|  |     - mariadb | ||||||
|  |     - proxy | ||||||
|  |     - docker | ||||||
|  |     - gitea | ||||||
|  |     - bitwarden | ||||||
							
								
								
									
										17
									
								
								roles/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								roles/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,17 +0,0 @@ | |||||||
| /* |  | ||||||
| !.gitignore |  | ||||||
| !requirements.yml |  | ||||||
| !base*/ |  | ||||||
| !bitwarden*/ |  | ||||||
| !docker*/ |  | ||||||
| !gitea*/ |  | ||||||
| !jenkins*/ |  | ||||||
| !libvirt*/ |  | ||||||
| !minecraft*/ |  | ||||||
| !nextcloud*/ |  | ||||||
| !nginx*/ |  | ||||||
| !prometheus*/ |  | ||||||
| !rsnapshot*/ |  | ||||||
| !traefik*/ |  | ||||||
| !unifi*/ |  | ||||||
| !wordpress*/ |  | ||||||
| @@ -1,8 +1,10 @@ | |||||||
|  | allow_reboot: true | ||||||
|  | manage_firewall: true | ||||||
| manage_network: false | manage_network: false | ||||||
| network_type: static | network_type: static | ||||||
| allow_reboot: true |  | ||||||
|  |  | ||||||
| packages: | packages: | ||||||
|  |   - apache2-utils | ||||||
|   - cryptsetup |   - cryptsetup | ||||||
|   - curl |   - curl | ||||||
|   - dnsutils |   - dnsutils | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| deb http://deb.debian.org/debian buster-backports main |  | ||||||
| @@ -1,12 +1,30 @@ | |||||||
| - name: Reboot host | - name: Reboot host | ||||||
|   reboot: |   ansible.builtin.reboot: | ||||||
|     msg: "Reboot initiated by Ansible" |     msg: "Reboot initiated by Ansible" | ||||||
|     connect_timeout: 5 |     connect_timeout: 5 | ||||||
|   listen: reboot_host |   listen: reboot_host | ||||||
|   when: allow_reboot |   when: allow_reboot | ||||||
|  |  | ||||||
| - name: Restart WireGuard | - name: Restart WireGuard | ||||||
|   service: |   ansible.builtin.service: | ||||||
|     name: wg-quick@wg0 |     name: wg-quick@wg0 | ||||||
|     state: restarted |     state: restarted | ||||||
|   listen: restart_wireguard |   listen: restart_wireguard | ||||||
|  |  | ||||||
|  | - name: Restart Fail2ban | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: fail2ban | ||||||
|  |     state: restarted | ||||||
|  |   listen: restart_fail2ban | ||||||
|  |  | ||||||
|  | - name: Restart ddclient | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: ddclient | ||||||
|  |     state: restarted | ||||||
|  |   listen: restart_ddclient | ||||||
|  |  | ||||||
|  | - name: Restart Samba | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: smbd | ||||||
|  |     state: restarted | ||||||
|  |   listen: restart_samba | ||||||
| @@ -1,15 +1,5 @@ | |||||||
| - name: 'Install Ansible dependency: python3-apt' | - name: Create Ansible's temporary remote directory | ||||||
|   shell: 'apt-get update && apt-get install python3-apt -y' |   ansible.builtin.file: | ||||||
|   args: |     path: "~/.ansible/tmp" | ||||||
|     creates: /usr/lib/python3/dist-packages/apt |     state: directory | ||||||
|     warn: false |     mode: 0700 | ||||||
|  |  | ||||||
| - name: Install additional Ansible dependencies |  | ||||||
|   apt: |  | ||||||
|     name: "{{ item }}" |  | ||||||
|     state: present |  | ||||||
|     force_apt_get: true |  | ||||||
|     update_cache: true |  | ||||||
|   loop: |  | ||||||
|     - aptitude |  | ||||||
|     - python3-docker |  | ||||||
|   | |||||||
| @@ -1,22 +1,17 @@ | |||||||
| - name: Install ddclient | - name: Install ddclient | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: ddclient |     name: ddclient | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Install ddclient settings | - name: Install ddclient settings | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: ddclient.conf.j2 |     src: ddclient.conf.j2 | ||||||
|     dest: /etc/ddclient.conf |     dest: /etc/ddclient.conf | ||||||
|  |     mode: 0600 | ||||||
|   register: ddclient_settings |   register: ddclient_settings | ||||||
|  |  | ||||||
| - name: Start ddclient and enable on boot | - name: Start ddclient and enable on boot | ||||||
|   service: |   ansible.builtin.service: | ||||||
|     name: ddclient |     name: ddclient | ||||||
|     state: started |     state: started | ||||||
|     enabled: true |     enabled: true | ||||||
|  |  | ||||||
| - name: Restart ddclient |  | ||||||
|   service: |  | ||||||
|     name: ddclient |  | ||||||
|     state: restarted |  | ||||||
|   when: ddclient_settings.changed |  | ||||||
|   | |||||||
							
								
								
									
										48
									
								
								roles/base/tasks/firewall.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								roles/base/tasks/firewall.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | - name: Install the Uncomplicated Firewall | ||||||
|  |   ansible.builtin.apt: | ||||||
|  |     name: ufw | ||||||
|  |     state: present | ||||||
|  |  | ||||||
|  | - name: Install Fail2ban | ||||||
|  |   ansible.builtin.apt: | ||||||
|  |     name: fail2ban | ||||||
|  |     state: present | ||||||
|  |  | ||||||
|  | - name: Deny incoming traffic by default | ||||||
|  |   community.general.ufw: | ||||||
|  |     default: deny | ||||||
|  |     direction: incoming | ||||||
|  |  | ||||||
|  | - name: Allow outgoing traffic by default | ||||||
|  |   community.general.ufw: | ||||||
|  |     default: allow | ||||||
|  |     direction: outgoing | ||||||
|  |  | ||||||
|  | - name: Allow OpenSSH with rate limiting | ||||||
|  |   community.general.ufw: | ||||||
|  |     name: ssh | ||||||
|  |     rule: limit | ||||||
|  |  | ||||||
|  | - name: Remove Fail2ban defaults-debian.conf | ||||||
|  |   ansible.builtin.file: | ||||||
|  |     path: /etc/fail2ban/jail.d/defaults-debian.conf | ||||||
|  |     state: absent | ||||||
|  |  | ||||||
|  | - name: Install OpenSSH's Fail2ban jail | ||||||
|  |   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 | ||||||
|  |   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 | ||||||
|  |   community.general.ufw: | ||||||
|  |     state: enabled | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| - name: Install msmtp | - name: Install msmtp | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: "{{ item }}" |     name: "{{ item }}" | ||||||
|     state: present |     state: present | ||||||
|   loop: |   loop: | ||||||
| @@ -8,12 +8,13 @@ | |||||||
|     - mailutils |     - mailutils | ||||||
|  |  | ||||||
| - name: Install msmtp configuration | - name: Install msmtp configuration | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: msmtprc.j2 |     src: msmtprc.j2 | ||||||
|     dest: /root/.msmtprc |     dest: /root/.msmtprc | ||||||
|     mode: 0700 |     mode: 0600 | ||||||
|  |  | ||||||
| - name: Install /etc/aliases | - name: Install /etc/aliases | ||||||
|   copy: |   ansible.builtin.copy: | ||||||
|     dest: /etc/aliases |     dest: /etc/aliases | ||||||
|     content: "root: {{ mail.rootalias }}" |     content: "root: {{ mail.rootalias }}" | ||||||
|  |     mode: 0644 | ||||||
|   | |||||||
| @@ -1,21 +1,37 @@ | |||||||
| - import_tasks: ansible.yml | - name: Import Ansible tasks | ||||||
|  |   ansible.builtin.import_tasks: ansible.yml | ||||||
|   tags: ansible |   tags: ansible | ||||||
|  |  | ||||||
| - import_tasks: system.yml | - name: Import System tasks | ||||||
|  |   ansible.builtin.import_tasks: system.yml | ||||||
|   tags: system |   tags: system | ||||||
|  |  | ||||||
| - import_tasks: network.yml | - name: Import Firewall tasks | ||||||
|  |   ansible.builtin.import_tasks: firewall.yml | ||||||
|  |   tags: firewall | ||||||
|  |   when: manage_firewall | ||||||
|  |  | ||||||
|  | - name: Import Network tasks | ||||||
|  |   ansible.builtin.import_tasks: network.yml | ||||||
|   tags: network |   tags: network | ||||||
|   when: manage_network |   when: manage_network | ||||||
|  |  | ||||||
| - import_tasks: mail.yml | - name: Import Mail tasks | ||||||
|  |   ansible.builtin.import_tasks: mail.yml | ||||||
|   tags: mail |   tags: mail | ||||||
|   when: mail is defined |   when: mail is defined | ||||||
|  |  | ||||||
| - import_tasks: ddclient.yml | - name: Import ddclient tasks | ||||||
|  |   ansible.builtin.import_tasks: ddclient.yml | ||||||
|   tags: ddclient |   tags: ddclient | ||||||
|   when: ddclient is defined |   when: ddclient is defined | ||||||
|  |  | ||||||
| - import_tasks: wireguard.yml | - name: Import WireGuard tasks | ||||||
|  |   ansible.builtin.import_tasks: wireguard.yml | ||||||
|   tags: wireguard |   tags: wireguard | ||||||
|   when: wireguard is defined |   when: wireguard is defined | ||||||
|  |  | ||||||
|  | - name: Import Samba tasks | ||||||
|  |   ansible.builtin.import_tasks: samba.yml | ||||||
|  |   tags: samba | ||||||
|  |   when: samba is defined | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| - name: Install network interfaces file | - name: Install network interfaces file | ||||||
|   copy: |   ansible.builtin.copy: | ||||||
|     src: network-interfaces.cfg |     src: network-interfaces.cfg | ||||||
|     dest: /etc/network/interfaces |     dest: /etc/network/interfaces | ||||||
|     owner: root |     owner: root | ||||||
| @@ -7,13 +7,9 @@ | |||||||
|     mode: '0644' |     mode: '0644' | ||||||
|  |  | ||||||
| - name: Install network interfaces | - name: Install network interfaces | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: "interface.j2" |     src: "interface.j2" | ||||||
|     dest: "/etc/network/interfaces.d/{{ item.name }}" |     dest: "/etc/network/interfaces.d/{{ item.name }}" | ||||||
|  |     mode: 0400 | ||||||
|   loop: "{{ interfaces }}" |   loop: "{{ interfaces }}" | ||||||
|   notify: reboot_host |   notify: reboot_host | ||||||
|  |  | ||||||
| - name: Install bridge utilities |  | ||||||
|   apt: |  | ||||||
|     name: bridge-utils |  | ||||||
|     state: present |  | ||||||
|   | |||||||
							
								
								
									
										53
									
								
								roles/base/tasks/samba.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								roles/base/tasks/samba.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | - name: Install Samba | ||||||
|  |   ansible.builtin.apt: | ||||||
|  |     name: samba | ||||||
|  |     state: present | ||||||
|  |  | ||||||
|  | - name: Create nologin shell accounts for Samba | ||||||
|  |   ansible.builtin.user: | ||||||
|  |     name: "{{ item.name }}" | ||||||
|  |     state: present | ||||||
|  |     shell: /usr/sbin/nologin | ||||||
|  |     createhome: false | ||||||
|  |     system: yes | ||||||
|  |   loop: "{{ samba.users }}" | ||||||
|  |   when: item.manage_user is defined and item.manage_user is true | ||||||
|  |  | ||||||
|  | - name: Create Samba users | ||||||
|  |   ansible.builtin.shell: "smbpasswd -a {{ 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 }}" | ||||||
|  |     owner: "{{ item.owner }}" | ||||||
|  |     group: "{{ item.group }}" | ||||||
|  |     state: directory | ||||||
|  |     mode: 0755 | ||||||
|  |   loop: "{{ samba.shares }}" | ||||||
|  |  | ||||||
|  | - name: Configure Samba shares | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: smb.conf.j2 | ||||||
|  |     dest: /etc/samba/smb.conf | ||||||
|  |   notify: restart_samba | ||||||
|  |  | ||||||
|  | - name: Start smbd and enable on boot | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: smbd | ||||||
|  |     state: started | ||||||
|  |     enabled: true | ||||||
|  |  | ||||||
|  | - name: Allow SMB connections | ||||||
|  |   community.general.ufw: | ||||||
|  |     rule: allow | ||||||
|  |     port: 445 | ||||||
|  |     proto: tcp | ||||||
|  |     from: "{{ item }}" | ||||||
|  |     state: enabled | ||||||
|  |   loop: "{{ samba.firewall }}" | ||||||
|  |   when: manage_firewall | ||||||
| @@ -1,23 +1,35 @@ | |||||||
| - name: Install useful software | - name: Install useful software | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: "{{ packages }}" |     name: "{{ packages }}" | ||||||
|     state: present |     state: present | ||||||
|     update_cache: true |     update_cache: true | ||||||
|  |  | ||||||
| - name: Manage root authorized_keys | - name: Manage root authorized_keys | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: authorized_keys.j2 |     src: authorized_keys.j2 | ||||||
|     dest: /root/.ssh/authorized_keys |     dest: /root/.ssh/authorized_keys | ||||||
|  |     mode: 0400 | ||||||
|   when: authorized_keys is defined |   when: authorized_keys is defined | ||||||
|  |  | ||||||
| - name: Install btrfs-tools | - name: Create system users | ||||||
|   apt: |   ansible.builtin.user: | ||||||
|     name: btrfs-tools |     name: "{{ item.name }}" | ||||||
|     state: present |     state: present | ||||||
|   when: btrfs_support is defined and btrfs_support | bool == true |     shell: "{{ item.shell | default('/bin/bash') }}" | ||||||
|  |     create_home: "{{ item.home | default(false) }}" | ||||||
|  |   loop: "{{ users }}" | ||||||
|  |   when: users is defined | ||||||
|  |  | ||||||
|  | - name: Set authorized_keys for system users | ||||||
|  |   ansible.posix.authorized_key: | ||||||
|  |     user: "{{ item.key }}" | ||||||
|  |     key: "{{ item.value.key }}" | ||||||
|  |     state: present | ||||||
|  |   loop: "{{ users }}" | ||||||
|  |   when: users is defined and item.value.key is defined | ||||||
|  |  | ||||||
| - name: Manage filesystem mounts | - name: Manage filesystem mounts | ||||||
|   mount: |   ansible.posix.mount: | ||||||
|     path: "{{ item.path }}" |     path: "{{ item.path }}" | ||||||
|     src: "UUID={{ item.uuid }}" |     src: "UUID={{ item.uuid }}" | ||||||
|     fstype: "{{ item.fstype }}" |     fstype: "{{ item.fstype }}" | ||||||
|   | |||||||
| @@ -1,51 +1,39 @@ | |||||||
| # Copyright (C) 2021  Kris Lamoureux |  | ||||||
| # |  | ||||||
| # This program is free software: you can redistribute it and/or modify |  | ||||||
| # it under the terms of the GNU General Public License as published by |  | ||||||
| # the Free Software Foundation, version 3 of the License. |  | ||||||
| # |  | ||||||
| # This program is distributed in the hope that it will be useful, |  | ||||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| # GNU General Public License for more details. |  | ||||||
| # |  | ||||||
| # You should have received a copy of the GNU General Public License |  | ||||||
| # along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  |  | ||||||
| - name: Add Debian Buster backports |  | ||||||
|   copy: |  | ||||||
|     src: buster-backports.list |  | ||||||
|     dest: /etc/apt/sources.list.d/buster-backports.list |  | ||||||
|     owner: root |  | ||||||
|     group: root |  | ||||||
|     mode: '0644' |  | ||||||
|  |  | ||||||
| - name: Install WireGuard | - name: Install WireGuard | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: wireguard |     name: wireguard | ||||||
|     state: present |     state: present | ||||||
|     update_cache: true |     update_cache: true | ||||||
|  |  | ||||||
| - name: Generate WireGuard keys | - 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: |   args: | ||||||
|     chdir: /etc/wireguard/ |     chdir: /etc/wireguard/ | ||||||
|     creates: /etc/wireguard/privatekey |     creates: /etc/wireguard/privatekey | ||||||
|  |     executable: /usr/bin/bash | ||||||
|  |  | ||||||
| - name: Grab WireGuard private key for configuration | - name: Grab WireGuard private key for configuration | ||||||
|   slurp: |   ansible.builtin.slurp: | ||||||
|     src: /etc/wireguard/privatekey |     src: /etc/wireguard/privatekey | ||||||
|   register: wgkey |   register: wgkey | ||||||
|  |  | ||||||
| - name: Install WireGuard configuration | - name: Install WireGuard configuration | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: wireguard.j2 |     src: wireguard.j2 | ||||||
|     dest: /etc/wireguard/wg0.conf |     dest: /etc/wireguard/wg0.conf | ||||||
|   notify: |     mode: 0400 | ||||||
|     - restart_wireguard |   notify: restart_wireguard | ||||||
|  |  | ||||||
| - name: Start WireGuard interface | - name: Start WireGuard interface | ||||||
|   service: |   ansible.builtin.service: | ||||||
|     name: wg-quick@wg0 |     name: wg-quick@wg0 | ||||||
|     state: started |     state: started | ||||||
|     enabled: true |     enabled: true | ||||||
|  |  | ||||||
|  | - name: Add WireGuard firewall rule | ||||||
|  |   community.general.ufw: | ||||||
|  |     rule: allow | ||||||
|  |     port: "{{ wireguard.listenport }}" | ||||||
|  |     proto: udp | ||||||
|  |   when: wireguard.listenport is defined | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								roles/base/templates/fail2ban-allowlist.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								roles/base/templates/fail2ban-allowlist.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | [DEFAULT] | ||||||
|  | ignoreip = {% for host in fail2ban_ignoreip %}{{ host }}{% if not loop.last %} {% endif %}{% endfor %} | ||||||
							
								
								
									
										3
									
								
								roles/base/templates/fail2ban-ssh.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								roles/base/templates/fail2ban-ssh.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | [sshd] | ||||||
|  | mode = aggressive | ||||||
|  | enabled = true | ||||||
							
								
								
									
										28
									
								
								roles/base/templates/smb.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								roles/base/templates/smb.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | [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 | ||||||
|  | {% if share.guest_allow is defined and share.guest_allow %} | ||||||
|  |    guest ok = yes | ||||||
|  | {% else %} | ||||||
|  |    guest ok = no | ||||||
|  | {% endif %} | ||||||
|  |    read only = {{ 'yes' if share.read_only | default(false) else 'no' }} | ||||||
|  | {% if share.valid_users is defined %} | ||||||
|  |    valid users = {{ share.valid_users }} | ||||||
|  | {% endif %} | ||||||
|  | {% if share.force_user is defined %} | ||||||
|  |    force user = {{ share.force_user }} | ||||||
|  | {% endif %} | ||||||
|  | {% endfor %} | ||||||
| @@ -1,4 +1,8 @@ | |||||||
| bitwarden_name: bitwarden | bitwarden_name: bitwarden | ||||||
| bitwarden_root: "/opt/{{ bitwarden_name }}" | bitwarden_root: "/var/lib/{{ bitwarden_name }}" | ||||||
|  | bitwarden_logs_identity: "{{ bitwarden_root }}/bwdata/logs/identity/Identity" | ||||||
|  | bitwarden_logs_identity_date: "{{ ansible_date_time.year }}{{ ansible_date_time.month }}{{ ansible_date_time.day }}" | ||||||
|  | bitwarden_database: "{{ bitwarden_name }}" | ||||||
|  | bitwarden_realips: "172.16.0.0/12" | ||||||
| bitwarden_standalone: false | bitwarden_standalone: false | ||||||
| bitwarden_production: false | bitwarden_production: false | ||||||
|   | |||||||
| @@ -1,7 +1,16 @@ | |||||||
| - name: Rebuild Bitwarden | - name: Stop Bitwarden for rebuild | ||||||
|   shell: "{{ bitwarden_root }}/bitwarden.sh rebuild" |   ansible.builtin.service: | ||||||
|  |     name: "{{ bitwarden_name }}" | ||||||
|  |     state: stopped | ||||||
|   listen: rebuild_bitwarden |   listen: rebuild_bitwarden | ||||||
|  |  | ||||||
| - name: Start Bitwarden | - name: Rebuild Bitwarden | ||||||
|   shell: "{{ bitwarden_root }}/bitwarden.sh start" |   ansible.builtin.shell: "{{ bitwarden_root }}/bitwarden.sh rebuild" | ||||||
|   listen: start_bitwarden |   listen: rebuild_bitwarden | ||||||
|  |  | ||||||
|  | - name: Start Bitwarden after rebuild | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: "{{ bitwarden_name }}" | ||||||
|  |     state: started | ||||||
|  |     enabled: true | ||||||
|  |   listen: rebuild_bitwarden | ||||||
|   | |||||||
| @@ -1,76 +1,104 @@ | |||||||
| - name: Install expect | - name: Install expect | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: expect |     name: expect | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Create Bitwarden directory | - name: Create Bitwarden directory | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ bitwarden_root }}" |     path: "{{ bitwarden_root }}" | ||||||
|     state: directory |     state: directory | ||||||
|  |  | ||||||
| - name: Download Bitwarden script | - name: Download Bitwarden script | ||||||
|   get_url: |   ansible.builtin.get_url: | ||||||
|     url: "https://raw.githubusercontent.com/\ |     url: "https://raw.githubusercontent.com/\ | ||||||
|           bitwarden/server/master/scripts/bitwarden.sh" |           bitwarden/self-host/master/bitwarden.sh" | ||||||
|     dest: "{{ bitwarden_root }}" |     dest: "{{ bitwarden_root }}" | ||||||
|     mode: u+x |     mode: u+x | ||||||
|  |  | ||||||
| - name: Install Bitwarden script wrapper | - name: Install Bitwarden script wrapper | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: bw_wrapper.j2 |     src: bw_wrapper.j2 | ||||||
|     dest: "{{ bitwarden_root }}/bw_wrapper" |     dest: "{{ bitwarden_root }}/bw_wrapper" | ||||||
|     mode: u+x |     mode: u+x | ||||||
|  |  | ||||||
| - name: Run Bitwarden installation script | - name: Run Bitwarden installation script | ||||||
|   shell: "{{ bitwarden_root }}/bw_wrapper" |   ansible.builtin.shell: "{{ bitwarden_root }}/bw_wrapper" | ||||||
|   args: |   args: | ||||||
|     creates: "{{ bitwarden_root }}/bwdata/config.yml" |     creates: "{{ bitwarden_root }}/bwdata/config.yml" | ||||||
|   notify: start_bitwarden |  | ||||||
|  |  | ||||||
| - name: Install docker-compose override | - name: Install docker-compose override | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: compose.override.yml.j2 |     src: compose.override.yml.j2 | ||||||
|     dest: "{{ bitwarden_root }}/bwdata/docker/docker-compose.override.yml" |     dest: "{{ bitwarden_root }}/bwdata/docker/docker-compose.override.yml" | ||||||
|   notify: |   when: traefik_version is defined | ||||||
|     - rebuild_bitwarden |   notify: rebuild_bitwarden | ||||||
|     - start_bitwarden |  | ||||||
|  |  | ||||||
| - name: Disable bitwarden-nginx HTTP on 80 | - name: Disable bitwarden-nginx HTTP on 80 | ||||||
|   replace: |   ansible.builtin.replace: | ||||||
|     path: "{{ bitwarden_root }}/bwdata/config.yml" |     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||||
|     regexp: "^http_port: 80$" |     regexp: "^http_port: 80$" | ||||||
|     replace: "http_port: 8080" |     replace: "http_port: 127.0.0.1:8080" | ||||||
|   when: not bitwarden_standalone |   when: not bitwarden_standalone | ||||||
|   notify: |   notify: rebuild_bitwarden | ||||||
|     - rebuild_bitwarden |  | ||||||
|     - start_bitwarden |  | ||||||
|  |  | ||||||
| - name: Disable bitwarden-nginx HTTPS on 443 | - name: Disable bitwarden-nginx HTTPS on 443 | ||||||
|   replace: |   ansible.builtin.replace: | ||||||
|     path: "{{ bitwarden_root }}/bwdata/config.yml" |     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||||
|     regexp: "^https_port: 443$" |     regexp: "^https_port: 443$" | ||||||
|     replace: "https_port: 8443" |     replace: "https_port: 127.0.0.1:8443" | ||||||
|   when: not bitwarden_standalone |   when: not bitwarden_standalone | ||||||
|   notify: |   notify: rebuild_bitwarden | ||||||
|     - rebuild_bitwarden |  | ||||||
|     - start_bitwarden |  | ||||||
|  |  | ||||||
| - name: Disable Bitwarden managed Lets Encrypt | - name: Disable Bitwarden managed Lets Encrypt | ||||||
|   replace: |   ansible.builtin.replace: | ||||||
|     path: "{{ bitwarden_root }}/bwdata/config.yml" |     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||||
|     regexp: "^ssl_managed_lets_encrypt: true$" |     regexp: "^ssl_managed_lets_encrypt: true$" | ||||||
|     replace: "ssl_managed_lets_encrypt: false" |     replace: "ssl_managed_lets_encrypt: false" | ||||||
|   when: not bitwarden_standalone or not bitwarden_production |   when: not bitwarden_standalone or not bitwarden_production | ||||||
|   notify: |   notify: rebuild_bitwarden | ||||||
|     - rebuild_bitwarden |  | ||||||
|     - start_bitwarden |  | ||||||
|  |  | ||||||
| - name: Disable Bitwarden managed SSL | - name: Disable Bitwarden managed SSL | ||||||
|   replace: |   ansible.builtin.replace: | ||||||
|     path: "{{ bitwarden_root }}/bwdata/config.yml" |     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||||
|     regexp: "^ssl: true$" |     regexp: "^ssl: true$" | ||||||
|     replace: "ssl: false" |     replace: "ssl: false" | ||||||
|   when: not bitwarden_standalone |   when: not bitwarden_standalone | ||||||
|   notify: |   notify: rebuild_bitwarden | ||||||
|     - rebuild_bitwarden |  | ||||||
|     - start_bitwarden | - name: Define reverse proxy servers | ||||||
|  |   ansible.builtin.lineinfile: | ||||||
|  |     path: "{{ bitwarden_root }}/bwdata/config.yml" | ||||||
|  |     line: "- {{ bitwarden_realips }}" | ||||||
|  |     insertafter: "^real_ips" | ||||||
|  |   notify: rebuild_bitwarden | ||||||
|  |  | ||||||
|  | - name: Install Bitwarden systemd service | ||||||
|  |   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 | ||||||
|  |   ansible.builtin.file: | ||||||
|  |     path: "{{ bitwarden_logs_identity }}" | ||||||
|  |     state: directory | ||||||
|  |   register: bitwarden_logs | ||||||
|  |  | ||||||
|  | - name: Create Bitwarden's initial log 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 | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: fail2ban-jail.conf.j2 | ||||||
|  |     dest: /etc/fail2ban/jail.d/bitwarden.conf | ||||||
|  |   notify: restart_fail2ban | ||||||
|  |  | ||||||
|  | - name: Reload systemd manager configuration | ||||||
|  |   ansible.builtin.systemd: | ||||||
|  |     daemon_reload: true | ||||||
|  |   when: bitwarden_systemd.changed | ||||||
|  |   notify: rebuild_bitwarden | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								roles/bitwarden/templates/bitwarden.service.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								roles/bitwarden/templates/bitwarden.service.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | [Unit] | ||||||
|  | Description=Bitwarden Password Manager Server | ||||||
|  | PartOf=docker.service | ||||||
|  | After=docker.service | ||||||
|  |  | ||||||
|  | [Service] | ||||||
|  | Type=oneshot | ||||||
|  | RemainAfterExit=true | ||||||
|  | ExecStart={{ bitwarden_root }}/bitwarden.sh start | ||||||
|  | ExecStop={{ bitwarden_root }}/bitwarden.sh stop | ||||||
|  |  | ||||||
|  | [Install] | ||||||
|  | WantedBy=multi-user.target | ||||||
| @@ -14,6 +14,9 @@ send "y\r" | |||||||
| send "n\r" | send "n\r" | ||||||
| {% endif %} | {% endif %} | ||||||
|  |  | ||||||
|  | expect "Enter the database name for your Bitwarden instance (ex. vault):" | ||||||
|  | send "{{ bitwarden_database }}\r" | ||||||
|  |  | ||||||
| expect "Enter your installation id (get at https://bitwarden.com/host):" | expect "Enter your installation id (get at https://bitwarden.com/host):" | ||||||
| send "{{ bitwarden_install_id }}\r" | send "{{ bitwarden_install_id }}\r" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | version: '3' | ||||||
|  |  | ||||||
| services: | services: | ||||||
|   nginx: |   nginx: | ||||||
|     networks: |     networks: | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								roles/bitwarden/templates/fail2ban-jail.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								roles/bitwarden/templates/fail2ban-jail.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | # {{ ansible_managed }} | ||||||
|  | [bitwarden] | ||||||
|  | enabled = true | ||||||
|  | filter = bitwarden | ||||||
|  | logpath = {{ bitwarden_root }}/bwdata/logs/identity/Identity/* | ||||||
|  | maxretry = 10 | ||||||
|  | findtime = 3600 | ||||||
|  | bantime = 900 | ||||||
|  | action = iptables-allports | ||||||
							
								
								
									
										6
									
								
								roles/docker/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								roles/docker/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | docker_compose_root: /var/lib/compose | ||||||
|  | docker_compose_service: compose | ||||||
|  | docker_compose: /usr/bin/docker-compose | ||||||
|  | docker_repos_keys: "{{ docker_repos_path }}/.keys" | ||||||
|  | docker_repos_keytype: rsa | ||||||
|  | docker_repos_path: /srv/compose_repos | ||||||
| @@ -1 +0,0 @@ | |||||||
| deb [arch=amd64] https://download.docker.com/linux/debian buster stable |  | ||||||
							
								
								
									
										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,38 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
|  |  | ||||||
| # Github username and repo name |  | ||||||
| user="docker" |  | ||||||
| repo="compose" |  | ||||||
|  |  | ||||||
| # Retrieve the latest version number |  | ||||||
| addr="https://github.com/$user/$repo/releases/latest" |  | ||||||
| page=$(curl -s $addr | grep -o releases/tag/*.*\") |  | ||||||
| version=$(echo $page | awk '{print substr($1, 14, length($1) - 14)}') |  | ||||||
|  |  | ||||||
| # Download prep |  | ||||||
| url="https://github.com/$user/$repo/releases/download/$version" |  | ||||||
| file="docker-compose-$(uname -s)-$(uname -m)" |  | ||||||
|  |  | ||||||
| # Download latest Docker Compose if that version hasn't been downloaded |  | ||||||
| if [ ! -f /tmp/docker_compose_$version ]; then |  | ||||||
|   curl -L $url/$file -o /tmp/docker-compose_$version |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| # Is it already installed? |  | ||||||
| if installed=$(which docker-compose); then |  | ||||||
|  |  | ||||||
|   new_chksum=$(sha256sum /tmp/docker-compose_$version) |  | ||||||
|   old_chksum=$(sha256sum /usr/local/bin/docker-compose) |  | ||||||
|  |  | ||||||
|   # If checksums are different, delete and install new version |  | ||||||
|   if [ ! "$new_chksum" = "$old_chksum" ]; then |  | ||||||
|     rm /usr/local/bin/docker-compose |  | ||||||
|     mv /tmp/docker-compose_$version /usr/local/bin/docker-compose |  | ||||||
|     chmod +x /usr/local/bin/docker-compose |  | ||||||
|   fi |  | ||||||
|  |  | ||||||
| else |  | ||||||
|   # It's not installed, so no need to remove |  | ||||||
|   mv /tmp/docker-compose_$version /usr/local/bin/docker-compose |  | ||||||
|   chmod +x /usr/local/bin/docker-compose |  | ||||||
| fi |  | ||||||
| @@ -1,61 +1,92 @@ | |||||||
| # Copyright (C) 2019  Kris Lamoureux | - name: Install Docker | ||||||
| # |   ansible.builtin.apt: | ||||||
| # This program is free software: you can redistribute it and/or modify |     name: ['docker.io', 'docker-compose'] | ||||||
| # it under the terms of the GNU General Public License as published by |  | ||||||
| # the Free Software Foundation, version 3 of the License. |  | ||||||
| # |  | ||||||
| # This program is distributed in the hope that it will be useful, |  | ||||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| # GNU General Public License for more details. |  | ||||||
| # |  | ||||||
| # You should have received a copy of the GNU General Public License |  | ||||||
| # along with this program.  If not, see <https://www.gnu.org/licenses/>. |  | ||||||
|  |  | ||||||
| - name: Remove old versions of Docker |  | ||||||
|   apt: |  | ||||||
|     name: ['docker', 'docker-engine', 'docker.io', 'containerd', 'runc'] |  | ||||||
|     state: absent |  | ||||||
|     update_cache: true |  | ||||||
|  |  | ||||||
| - name: Install HTTPS capability for apt |  | ||||||
|   apt: |  | ||||||
|     name: ['apt-transport-https', 'ca-certificates', |  | ||||||
|            'curl', 'gnupg2', 'software-properties-common'] |  | ||||||
|     state: present |  | ||||||
|  |  | ||||||
| - name: Install Docker's signing key |  | ||||||
|   apt_key: |  | ||||||
|     url: https://download.docker.com/linux/debian/gpg |  | ||||||
|     id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88 |  | ||||||
|     state: present |  | ||||||
|  |  | ||||||
| - name: Install Docker's stable repository |  | ||||||
|   template: |  | ||||||
|     src: docker-ce.list |  | ||||||
|     dest: /etc/apt/sources.list.d/docker-ce.list |  | ||||||
|  |  | ||||||
| - name: Install Docker CE |  | ||||||
|   apt: |  | ||||||
|     name: ['docker-ce', 'docker-ce-cli', 'containerd.io'] |  | ||||||
|     state: present |     state: present | ||||||
|     update_cache: true |     update_cache: true | ||||||
|  |  | ||||||
|  | - name: Create docker-compose root | ||||||
|  |   ansible.builtin.file: | ||||||
|  |     path: "{{ docker_compose_root }}" | ||||||
|  |     state: directory | ||||||
|  |     mode: 0500 | ||||||
|  |  | ||||||
|  | - name: Install docker-compose systemd service | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: docker-compose.service.j2 | ||||||
|  |     dest: "/etc/systemd/system/{{ docker_compose_service }}@.service" | ||||||
|  |     mode: 0400 | ||||||
|  |   notify: compose_systemd | ||||||
|  |  | ||||||
|  | - name: Create directories to clone docker-compose repositories | ||||||
|  |   ansible.builtin.file: | ||||||
|  |     path: "{{ item }}" | ||||||
|  |     state: directory | ||||||
|  |     mode: 0400 | ||||||
|  |   loop: | ||||||
|  |     - "{{ docker_repos_path }}" | ||||||
|  |     - "{{ docker_repos_keys }}" | ||||||
|  |   when: docker_compose_deploy is defined | ||||||
|  |  | ||||||
|  | - name: Generate OpenSSH deploy keys for docker-compose clones | ||||||
|  |   community.crypto.openssh_keypair: | ||||||
|  |     path: "{{ docker_repos_keys }}/id_{{ docker_repos_keytype }}" | ||||||
|  |     type: "{{ docker_repos_keytype }}" | ||||||
|  |     mode: 0400 | ||||||
|  |     state: present | ||||||
|  |   when: docker_compose_deploy is defined | ||||||
|  |  | ||||||
|  | - name: Clone external docker-compose projects | ||||||
|  |   ansible.builtin.git: | ||||||
|  |     repo: "{{ item.url }}" | ||||||
|  |     dest: "{{ docker_repos_path }}/{{ item.name }}" | ||||||
|  |     version: "{{ item.version | default('main') }}" | ||||||
|  |     force: true | ||||||
|  |     key_file: "{{ docker_repos_keys }}/id_{{ docker_repos_keytype }}" | ||||||
|  |   when: docker_compose_deploy is defined | ||||||
|  |   loop: "{{ docker_compose_deploy }}" | ||||||
|  |  | ||||||
|  | - name: Create directories for docker-compose projects using the systemd service | ||||||
|  |   ansible.builtin.file: | ||||||
|  |     path: "{{ docker_compose_root }}/{{ item.name }}" | ||||||
|  |     state: directory | ||||||
|  |     mode: 0400 | ||||||
|  |   loop: "{{ docker_compose_deploy }}" | ||||||
|  |   when: docker_compose_deploy is defined | ||||||
|  |  | ||||||
|  | - name: Copy docker-compose.yml files to their service directories | ||||||
|  |   ansible.builtin.copy: | ||||||
|  |     src: "{{ docker_repos_path }}/{{ item.name }}/{{ item.path | default('docker-compose.yml') }}" | ||||||
|  |     dest: "{{ docker_compose_root }}/{{ item.name }}/docker-compose.yml" | ||||||
|  |     remote_src: yes | ||||||
|  |   loop: "{{ docker_compose_deploy }}" | ||||||
|  |   when: docker_compose_deploy is defined | ||||||
|  |  | ||||||
|  | - name: Set environment variables for docker-compose projects | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: docker-compose-env.j2 | ||||||
|  |     dest: "{{ docker_compose_root }}/{{ item.name }}/.env" | ||||||
|  |     mode: 0400 | ||||||
|  |   loop: "{{ docker_compose_deploy }}" | ||||||
|  |   when: docker_compose_deploy is defined and item.env is defined | ||||||
|  |  | ||||||
| - name: Add users to docker group | - name: Add users to docker group | ||||||
|   user: |   ansible.builtin.user: | ||||||
|     name: "{{ item }}" |     name: "{{ item }}" | ||||||
|     groups: docker |     groups: docker | ||||||
|     append: true |     append: true | ||||||
|   loop: "{{ docker_users }}" |   loop: "{{ docker_users }}" | ||||||
|   when: docker_users is defined |   when: docker_users is defined | ||||||
|  |  | ||||||
| - name: Install docker-compose |  | ||||||
|   script: install-compose.sh |  | ||||||
|   args: |  | ||||||
|     creates: /usr/local/bin/docker-compose |  | ||||||
|  |  | ||||||
| - name: Start Docker and enable on boot | - name: Start Docker and enable on boot | ||||||
|   service: |   ansible.builtin.service: | ||||||
|     name: docker |     name: docker | ||||||
|     state: started |     state: started | ||||||
|     enabled: true |     enabled: true | ||||||
|  |  | ||||||
|  | - name: Start docker-compose services and enable on boot | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: "{{ docker_compose_service }}@{{ item.name }}" | ||||||
|  |     state: started | ||||||
|  |     enabled: true | ||||||
|  |   loop: "{{ docker_compose_deploy }}" | ||||||
|  |   when: item.enabled is defined and item.enabled is true | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								roles/docker/templates/docker-compose-env.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								roles/docker/templates/docker-compose-env.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | # {{ ansible_managed }} | ||||||
|  |  | ||||||
|  | {% if item.env is defined %} | ||||||
|  | {% for kvpair in item.env.items() %} | ||||||
|  | {{ kvpair.0 }}={{ kvpair.1 }} | ||||||
|  | {% endfor %} | ||||||
|  | {% endif %} | ||||||
							
								
								
									
										14
									
								
								roles/docker/templates/docker-compose.service.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								roles/docker/templates/docker-compose.service.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | [Unit] | ||||||
|  | Description=%i docker-compose service | ||||||
|  | PartOf=docker.service | ||||||
|  | After=docker.service | ||||||
|  |  | ||||||
|  | [Service] | ||||||
|  | Type=oneshot | ||||||
|  | RemainAfterExit=true | ||||||
|  | WorkingDirectory={{ docker_compose_root }}/%i | ||||||
|  | ExecStart={{ docker_compose }} up -d --remove-orphans | ||||||
|  | ExecStop={{ docker_compose }} down | ||||||
|  |  | ||||||
|  | [Install] | ||||||
|  | WantedBy=multi-user.target | ||||||
| @@ -1,11 +1,22 @@ | |||||||
| # container settings | # container settings | ||||||
| gitea_name: gitea | gitea_name: gitea | ||||||
| gitea_dbname: "{{ gitea_name }}-db" | gitea_sshport: "222" | ||||||
| gitea_ports: "222:22" | 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: "https://{{ gitea_domain }}" | ||||||
|  | gitea_signup: true | ||||||
|  |  | ||||||
| # database settings | # database settings | ||||||
| gitea_dbuser: "{{ gitea_dbname }}" | gitea_dbtype: mysql | ||||||
|  | gitea_dbhost: host.docker.internal | ||||||
|  | gitea_dbname: "{{ gitea_name }}" | ||||||
|  | gitea_dbuser: "{{ gitea_name }}" | ||||||
|  |  | ||||||
|  | # proxy settings | ||||||
|  | gitea_proxy_limit: "1" | ||||||
|  | gitea_trusted_proxies: "172.16.0.0/12" | ||||||
|  |  | ||||||
| # host | # host | ||||||
| gitea_root: "/opt/{{ gitea_name }}/data" | gitea_root: "{{ docker_compose_root }}/{{ gitea_name }}" | ||||||
| gitea_dbroot: "/opt/{{ gitea_name }}/database" |  | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								roles/gitea/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								roles/gitea/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | - name: Restart Gitea | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: "{{ docker_compose_service }}@{{ gitea_name }}" | ||||||
|  |     state: restarted | ||||||
|  |   listen: restart_gitea | ||||||
| @@ -1,54 +1,111 @@ | |||||||
| - name: Create Gitea Network | - name: Create Gitea directory | ||||||
|   docker_network: |   ansible.builtin.file: | ||||||
|     name: "{{ gitea_name }}" |     path: "{{ gitea_root }}" | ||||||
|  |     state: directory | ||||||
|  |  | ||||||
| - name: Start Gitea's database container | - name: Create Gitea database | ||||||
|   docker_container: |   community.mysql.mysql_db: | ||||||
|     name: "{{ gitea_dbname }}" |     name: "{{ gitea_dbname }}" | ||||||
|     image: mariadb:{{ gitea_dbversion }} |     state: present | ||||||
|     state: started |     login_unix_socket: /var/run/mysqld/mysqld.sock | ||||||
|     restart_policy: always |  | ||||||
|     volumes: "{{ gitea_dbroot }}:/var/lib/mysql" |  | ||||||
|     networks_cli_compatible: true |  | ||||||
|     networks: |  | ||||||
|       - name: "{{ gitea_name }}" |  | ||||||
|     env: |  | ||||||
|       MYSQL_RANDOM_ROOT_PASSWORD: "true" |  | ||||||
|       MYSQL_DATABASE: "{{ gitea_dbname }}" |  | ||||||
|       MYSQL_USER: "{{ gitea_dbuser }}" |  | ||||||
|       MYSQL_PASSWORD: "{{ gitea_dbpass }}" |  | ||||||
|  |  | ||||||
| - name: Start Gitea container | - name: Create Gitea database user | ||||||
|   docker_container: |   community.mysql.mysql_user: | ||||||
|     name: "{{ gitea_name }}" |     name: "{{ gitea_dbuser }}" | ||||||
|     image: gitea/gitea:{{ gitea_version }} |     password: "{{ gitea_dbpass }}" | ||||||
|  |     host: '%' | ||||||
|  |     state: present | ||||||
|  |     priv: "{{ gitea_dbname }}.*:ALL" | ||||||
|  |     login_unix_socket: /var/run/mysqld/mysqld.sock | ||||||
|  |  | ||||||
|  | - name: Create git user | ||||||
|  |   ansible.builtin.user: | ||||||
|  |     name: git | ||||||
|  |     state: present | ||||||
|  |  | ||||||
|  | - name: Git user uid | ||||||
|  |   ansible.builtin.getent: | ||||||
|  |     database: passwd | ||||||
|  |     key: git | ||||||
|  |  | ||||||
|  | - name: Git user gid | ||||||
|  |   ansible.builtin.getent: | ||||||
|  |     database: group | ||||||
|  |     key: git | ||||||
|  |  | ||||||
|  | - name: Create git's .ssh directory | ||||||
|  |   ansible.builtin.file: | ||||||
|  |     path: /home/git/.ssh | ||||||
|  |     state: directory | ||||||
|  |  | ||||||
|  | - name: Generate git's SSH keys | ||||||
|  |   community.crypto.openssh_keypair: | ||||||
|  |     path: /home/git/.ssh/id_rsa | ||||||
|  |  | ||||||
|  | - name: Find git's public SSH key | ||||||
|  |   ansible.builtin.slurp: | ||||||
|  |     src: /home/git/.ssh/id_rsa.pub | ||||||
|  |   register: git_rsapub | ||||||
|  |  | ||||||
|  | - name: Get stats on git's authorized_keys file | ||||||
|  |   ansible.builtin.stat: | ||||||
|  |     path: /home/git/.ssh/authorized_keys | ||||||
|  |   register: git_authkeys | ||||||
|  |  | ||||||
|  | - name: Create git's authorized_keys 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 | ||||||
|  |   ansible.builtin.lineinfile: | ||||||
|  |     path: /home/git/.ssh/authorized_keys | ||||||
|  |     regex: "^ssh-rsa" | ||||||
|  |     line: "{{ git_rsapub['content'] | b64decode }}" | ||||||
|  |  | ||||||
|  | - name: Create Gitea host script for SSH | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: gitea.sh.j2 | ||||||
|  |     dest: /usr/local/bin/gitea | ||||||
|  |     mode: 0755 | ||||||
|  |  | ||||||
|  | - name: Install Gitea's docker-compose file | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: docker-compose.yml.j2 | ||||||
|  |     dest: "{{ gitea_root }}/docker-compose.yml" | ||||||
|  |   notify: restart_gitea | ||||||
|  |  | ||||||
|  | - name: Install Gitea's docker-compose variables | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: compose-env.j2 | ||||||
|  |     dest: "{{ gitea_root }}/.env" | ||||||
|  |   notify: restart_gitea | ||||||
|  |  | ||||||
|  | - name: Create Gitea's logging directory | ||||||
|  |   ansible.builtin.file: | ||||||
|  |     name: /var/log/gitea | ||||||
|  |     state: directory | ||||||
|  |  | ||||||
|  | - name: Create Gitea's initial log file | ||||||
|  |   ansible.builtin.file: | ||||||
|  |     name: /var/log/gitea/gitea.log | ||||||
|  |     state: touch | ||||||
|  |  | ||||||
|  | - name: Install Gitea's Fail2ban filter | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: fail2ban-filter.conf.j2 | ||||||
|  |     dest: /etc/fail2ban/filter.d/gitea.conf | ||||||
|  |   notify: restart_fail2ban | ||||||
|  |  | ||||||
|  | - name: Install Gitea's Fail2ban jail | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: fail2ban-jail.conf.j2 | ||||||
|  |     dest: /etc/fail2ban/jail.d/gitea.conf | ||||||
|  |   notify: restart_fail2ban | ||||||
|  |  | ||||||
|  | - name: Start and enable Gitea service | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: "{{ docker_compose_service }}@{{ gitea_name }}" | ||||||
|     state: started |     state: started | ||||||
|     restart_policy: always |     enabled: true | ||||||
|     networks_cli_compatible: true |  | ||||||
|     ports: "{{ gitea_ports }}" |  | ||||||
|     networks: |  | ||||||
|       - name: "{{ gitea_name }}" |  | ||||||
|       - name: traefik |  | ||||||
|     volumes: |  | ||||||
|       - "{{ gitea_root }}:/data" |  | ||||||
|       - /etc/timezone:/etc/timezone:ro |  | ||||||
|       - /etc/localtime:/etc/localtime:ro |  | ||||||
|     env: |  | ||||||
|       USER_UID: "1000" |  | ||||||
|       USER_GID: "1000" |  | ||||||
|       DB_TYPE: mysql |  | ||||||
|       DB_HOST: "{{ gitea_dbname }}" |  | ||||||
|       DB_NAME: "{{ gitea_dbname }}" |  | ||||||
|       DB_USER: "{{ gitea_dbuser }}" |  | ||||||
|       DB_PASSWD: "{{ gitea_dbpass }}" |  | ||||||
|       ROOT_URL: "https://{{ gitea_domain }}/" |  | ||||||
|       SSH_DOMAIN: "{{ gitea_domain }}" |  | ||||||
|       DOMAIN: "{{ gitea_domain }}" |  | ||||||
|     labels: |  | ||||||
|       traefik.http.routers.gitea.rule: "Host(`{{ gitea_domain }}`)" |  | ||||||
|       traefik.http.routers.gitea.entrypoints: websecure |  | ||||||
|       traefik.http.routers.gitea.tls.certresolver: letsencrypt |  | ||||||
|       traefik.http.routers.gitea.middlewares: "securehttps@file" |  | ||||||
|       traefik.http.services.gitea.loadbalancer.server.port: "3000" |  | ||||||
|       traefik.docker.network: traefik |  | ||||||
|       traefik.enable: "true" |  | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								roles/gitea/templates/compose-env.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								roles/gitea/templates/compose-env.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | # {{ ansible_managed }} | ||||||
|  | gitea_version={{ gitea_version }} | ||||||
|  | gitea_name={{ gitea_name }} | ||||||
|  | gitea_domain={{ gitea_domain }} | ||||||
|  | gitea_rooturl={{ gitea_rooturl }} | ||||||
|  | gitea_web={{ gitea_web }} | ||||||
|  | gitea_ssh={{ gitea_ssh }} | ||||||
|  | gitea_dbtype={{ gitea_dbtype }} | ||||||
|  | gitea_dbhost={{ gitea_dbhost }} | ||||||
|  | gitea_dbname={{ gitea_dbname }} | ||||||
|  | gitea_dbuser={{ gitea_dbuser }} | ||||||
|  | gitea_dbpass={{ gitea_dbpass }} | ||||||
|  | gitea_proxy_limit={{ gitea_proxy_limit }} | ||||||
|  | gitea_trusted_proxies={{ gitea_trusted_proxies }} | ||||||
|  | {% if not gitea_signup %} | ||||||
|  | gitea_disable_registration=true | ||||||
|  | {% else %} | ||||||
|  | gitea_disable_registration=false | ||||||
|  | {% endif %} | ||||||
							
								
								
									
										36
									
								
								roles/gitea/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								roles/gitea/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | version: '3.7' | ||||||
|  |  | ||||||
|  | services: | ||||||
|  |   gitea: | ||||||
|  |     image: "gitea/gitea:${gitea_version}" | ||||||
|  |     container_name: "${gitea_name}" | ||||||
|  |     ports: | ||||||
|  |       - "${gitea_ssh}:22" | ||||||
|  |       - "${gitea_web}:3000" | ||||||
|  |     extra_hosts: | ||||||
|  |       - "host.docker.internal:host-gateway" | ||||||
|  |     environment: | ||||||
|  |       - USER_UID={{ getent_passwd.git[1] }} | ||||||
|  |       - USER_GID={{ getent_group.git[1] }} | ||||||
|  |       - GITEA__log__MODE=file | ||||||
|  |       - GITEA__server__ROOT_URL=${gitea_rooturl} | ||||||
|  |       - GITEA__server__DOMAIN=${gitea_domain} | ||||||
|  |       - GITEA__server__SSH_DOMAIN=${gitea_domain} | ||||||
|  |       - GITEA__database__DB_TYPE=${gitea_dbtype} | ||||||
|  |       - GITEA__database__HOST=${gitea_dbhost} | ||||||
|  |       - GITEA__database__NAME=${gitea_dbname} | ||||||
|  |       - GITEA__database__USER=${gitea_dbuser} | ||||||
|  |       - GITEA__database__PASSWD=${gitea_dbpass} | ||||||
|  |       - GITEA__security__INSTALL_LOCK=true | ||||||
|  |       - GITEA__security__REVERSE_PROXY_LIMIT=${gitea_proxy_limit} | ||||||
|  |       - GITEA__security__REVERSE_PROXY_TRUSTED_PROXIES=${gitea_trusted_proxies} | ||||||
|  |       - GITEA__service__DISABLE_REGISTRATION=${gitea_disable_registration} | ||||||
|  |     volumes: | ||||||
|  |       - {{ gitea_volume }}:/data | ||||||
|  |       - /home/git/.ssh:/data/git/.ssh | ||||||
|  |       - /var/log/gitea:/data/gitea/log | ||||||
|  |       - /etc/timezone:/etc/timezone:ro | ||||||
|  |       - /etc/localtime:/etc/localtime:ro | ||||||
|  |  | ||||||
|  | volumes: | ||||||
|  |   {{ gitea_volume }}: | ||||||
							
								
								
									
										4
									
								
								roles/gitea/templates/fail2ban-filter.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								roles/gitea/templates/fail2ban-filter.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | # {{ ansible_managed }} | ||||||
|  | [Definition] | ||||||
|  | failregex =  .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST> | ||||||
|  | ignoreregex = | ||||||
							
								
								
									
										18
									
								
								roles/gitea/templates/fail2ban-jail.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								roles/gitea/templates/fail2ban-jail.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | # {{ ansible_managed }} | ||||||
|  | [gitea] | ||||||
|  | enabled = true | ||||||
|  | filter = gitea | ||||||
|  | logpath = /var/log/gitea/gitea.log | ||||||
|  | maxretry = 10 | ||||||
|  | findtime = 3600 | ||||||
|  | bantime = 900 | ||||||
|  | action = iptables-allports | ||||||
|  |  | ||||||
|  | [gitea-docker] | ||||||
|  | enabled = true | ||||||
|  | filter = gitea | ||||||
|  | logpath = /var/log/gitea/gitea.log | ||||||
|  | maxretry = 10 | ||||||
|  | findtime = 3600 | ||||||
|  | bantime = 900 | ||||||
|  | action = iptables-allports[chain="FORWARD"] | ||||||
							
								
								
									
										2
									
								
								roles/gitea/templates/gitea.sh.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								roles/gitea/templates/gitea.sh.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | #!/bin/sh | ||||||
|  | ssh -p {{ gitea_sshport }} -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@" | ||||||
							
								
								
									
										4
									
								
								roles/jellyfin/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								roles/jellyfin/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | jellyfin_name: jellyfin | ||||||
|  | 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 | ||||||
							
								
								
									
										35
									
								
								roles/jellyfin/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								roles/jellyfin/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | - name: Create Jellyfin directory | ||||||
|  |   ansible.builtin.file: | ||||||
|  |     path: "{{ jellyfin_root }}" | ||||||
|  |     state: directory | ||||||
|  |     mode: 0500 | ||||||
|  |  | ||||||
|  | - 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 }} | ||||||
							
								
								
									
										30
									
								
								roles/jellyfin/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								roles/jellyfin/templates/docker-compose.yml.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | version: '3.7' | ||||||
|  |  | ||||||
|  | volumes: | ||||||
|  |   config: | ||||||
|  |   cache: | ||||||
|  |  | ||||||
|  | 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_media }}:/media | ||||||
| @@ -1 +0,0 @@ | |||||||
| deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main |  | ||||||
| @@ -1,10 +1,5 @@ | |||||||
| - name: Install GnuPG |  | ||||||
|   apt: |  | ||||||
|     name: gnupg |  | ||||||
|     state: present |  | ||||||
|  |  | ||||||
| - name: Create Jenkins user | - name: Create Jenkins user | ||||||
|   user: |   ansible.builtin.user: | ||||||
|     name: "{{ jenkins_user }}" |     name: "{{ jenkins_user }}" | ||||||
|     state: present |     state: present | ||||||
|     shell: /bin/bash |     shell: /bin/bash | ||||||
| @@ -12,35 +7,25 @@ | |||||||
|     generate_ssh_key: true |     generate_ssh_key: true | ||||||
|  |  | ||||||
| - name: Set Jenkins authorized key | - name: Set Jenkins authorized key | ||||||
|   authorized_key: |   ansible.posix.authorized_key: | ||||||
|     user: jenkins |     user: jenkins | ||||||
|     state: present |     state: present | ||||||
|     exclusive: true |     exclusive: true | ||||||
|     key: "{{ jenkins_sshkey }}" |     key: "{{ jenkins_sshkey }}" | ||||||
|  |  | ||||||
| - name: Give Jenkins user passwordless sudo | - name: Give Jenkins user passwordless sudo | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: jenkins_sudoers.j2 |     src: jenkins_sudoers.j2 | ||||||
|     dest: /etc/sudoers.d/{{ jenkins_user }} |     dest: /etc/sudoers.d/{{ jenkins_user }} | ||||||
|     validate: "visudo -cf %s" |     validate: "visudo -cf %s" | ||||||
|     mode: 0440 |     mode: 0440 | ||||||
|  |  | ||||||
| - name: Install Ansible source |  | ||||||
|   copy: |  | ||||||
|     src: ansible.list |  | ||||||
|     dest: /etc/apt/sources.list.d/ansible.list |  | ||||||
|  |  | ||||||
| - name: Add Ansible source key |  | ||||||
|   apt_key: |  | ||||||
|     keyserver: keyserver.ubuntu.com |  | ||||||
|     id: 93C4A3FD7BB9C367 |  | ||||||
|  |  | ||||||
| - name: Install Ansible | - name: Install Ansible | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: ansible |     name: ansible | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Install Java | - name: Install Java | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: default-jre |     name: default-jre | ||||||
|     state: present |     state: present | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| - import_tasks: agent.yml | - ansible.builtin.import_tasks: agent.yml | ||||||
|   when: jenkins_sshkey is defined |   when: jenkins_sshkey is defined | ||||||
|  |  | ||||||
| - import_tasks: server.yml | - ansible.builtin.import_tasks: server.yml | ||||||
|   when: jenkins_domain is defined |   when: jenkins_domain is defined | ||||||
|   | |||||||
| @@ -1,12 +1,12 @@ | |||||||
| - name: Create Jenkin's directory | - name: Create Jenkin's directory | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ jenkins_root }}" |     path: "{{ jenkins_root }}" | ||||||
|     state: directory |     state: directory | ||||||
|     owner: "1000" |     owner: "1000" | ||||||
|     group: "1000" |     group: "1000" | ||||||
|  |  | ||||||
| - name: Start Jenkins Container | - name: Start Jenkins Container | ||||||
|   docker_container: |   community.general.docker_container: | ||||||
|     name: "{{ jenkins_name }}" |     name: "{{ jenkins_name }}" | ||||||
|     image: jenkins/jenkins:{{ jenkins_version }} |     image: jenkins/jenkins:{{ jenkins_version }} | ||||||
|     state: started |     state: started | ||||||
|   | |||||||
| @@ -1,15 +1,15 @@ | |||||||
| - name: Install QEMU/KVM | - name: Install QEMU/KVM | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: qemu-kvm |     name: qemu-kvm | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Install Libvirt | - name: Install Libvirt | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: ["libvirt-clients", "libvirt-daemon-system"] |     name: ["libvirt-clients", "libvirt-daemon-system"] | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Add users to libvirt group | - name: Add users to libvirt group | ||||||
|   user: |   ansible.builtin.user: | ||||||
|     name: "{{ item }}" |     name: "{{ item }}" | ||||||
|     groups: libvirt |     groups: libvirt | ||||||
|     append: yes |     append: yes | ||||||
| @@ -17,12 +17,12 @@ | |||||||
|   when: libvirt_users is defined |   when: libvirt_users is defined | ||||||
|  |  | ||||||
| - name: Check for NODOWNLOAD file | - name: Check for NODOWNLOAD file | ||||||
|   stat: |   ansible.builtin.stat: | ||||||
|     path: /var/lib/libvirt/images/NODOWNLOAD |     path: /var/lib/libvirt/images/NODOWNLOAD | ||||||
|   register: NODOWNLOAD |   register: NODOWNLOAD | ||||||
|  |  | ||||||
| - name: Download GNU/Linux ISOs | - name: Download GNU/Linux ISOs | ||||||
|   get_url: |   ansible.builtin.get_url: | ||||||
|     url: "{{ item.url }}" |     url: "{{ item.url }}" | ||||||
|     dest: /var/lib/libvirt/images |     dest: /var/lib/libvirt/images | ||||||
|     checksum: "{{ item.hash }}" |     checksum: "{{ item.hash }}" | ||||||
| @@ -34,7 +34,7 @@ | |||||||
|  |  | ||||||
| # Prevent downloaded ISOs from being rehashed every run | # Prevent downloaded ISOs from being rehashed every run | ||||||
| - name: Create NODOWNLOAD file | - name: Create NODOWNLOAD file | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: /var/lib/libvirt/images/NODOWNLOAD |     path: /var/lib/libvirt/images/NODOWNLOAD | ||||||
|     state: touch |     state: touch | ||||||
|   when: download_isos.changed |   when: download_isos.changed | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								roles/mariadb/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								roles/mariadb/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | mariadb_trust: | ||||||
|  |   - "172.16.0.0/12" | ||||||
|  |   - "192.168.0.0/16" | ||||||
							
								
								
									
										25
									
								
								roles/mariadb/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								roles/mariadb/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | - name: Install MariaDB | ||||||
|  |   ansible.builtin.apt: | ||||||
|  |     name: mariadb-server | ||||||
|  |     state: present | ||||||
|  |  | ||||||
|  | - name: Change the bind-address to allow Docker | ||||||
|  |   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 | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: mariadb | ||||||
|  |     state: restarted | ||||||
|  |   when: mariadb_conf.changed | ||||||
|  |  | ||||||
|  | - name: Allow database connections | ||||||
|  |   community.general.ufw: | ||||||
|  |     rule: allow | ||||||
|  |     port: "3306" | ||||||
|  |     proto: tcp | ||||||
|  |     src: "{{ item }}" | ||||||
|  |   loop: "{{ mariadb_trust }}" | ||||||
| @@ -1,28 +1,28 @@ | |||||||
| - name: Install GPG | - name: Install GPG | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: gpg |     name: gpg | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Add AdoptOpenJDK's signing key | - name: Add AdoptOpenJDK's signing key | ||||||
|   apt_key: |   ansible.builtin.apt_key: | ||||||
|     id: 8ED17AF5D7E675EB3EE3BCE98AC3B29174885C03 |     id: 8ED17AF5D7E675EB3EE3BCE98AC3B29174885C03 | ||||||
|     url: https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public |     url: https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | ||||||
|  |  | ||||||
| - name: Install AdoptOpenJDK repository | - name: Install AdoptOpenJDK repository | ||||||
|   apt_repository: |   ansible.builtin.apt_repository: | ||||||
|     repo: deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main |     repo: deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main | ||||||
|     mode: 0644 |     mode: 0644 | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Install Java | - name: Install Java | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: "adoptopenjdk-{{ item.java.version }}-hotspot" |     name: "adoptopenjdk-{{ item.java.version }}-hotspot" | ||||||
|     state: present |     state: present | ||||||
|   when: item.java.version is defined |   when: item.java.version is defined | ||||||
|   loop: "{{ minecraft }}" |   loop: "{{ minecraft }}" | ||||||
|  |  | ||||||
| - name: "Install default Java, version {{ minecraft_java }}" | - name: "Install default Java, version {{ minecraft_java }}" | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: "{{ minecraft_java_pkg }}" |     name: "{{ minecraft_java_pkg }}" | ||||||
|     state: present |     state: present | ||||||
|   when: item.java.version is not defined |   when: item.java.version is not defined | ||||||
| @@ -30,7 +30,7 @@ | |||||||
|   register: minecraft_java_default |   register: minecraft_java_default | ||||||
|  |  | ||||||
| - name: "Activate default Java, version {{ minecraft_java }}" | - name: "Activate default Java, version {{ minecraft_java }}" | ||||||
|   alternatives: |   community.general.alternatives: | ||||||
|     name: java |     name: java | ||||||
|     path: "/usr/lib/jvm/{{ minecraft_java_pkg }}-amd64/bin/java" |     path: "/usr/lib/jvm/{{ minecraft_java_pkg }}-amd64/bin/java" | ||||||
|   when: minecraft_java_default.changed |   when: minecraft_java_default.changed | ||||||
|   | |||||||
| @@ -1,14 +1,14 @@ | |||||||
| - import_tasks: system.yml | - ansible.builtin.import_tasks: system.yml | ||||||
|   when: minecraft_eula |   when: minecraft_eula | ||||||
|  |  | ||||||
| - import_tasks: java.yml | - ansible.builtin.import_tasks: java.yml | ||||||
|   when: minecraft_eula |   when: minecraft_eula | ||||||
|  |  | ||||||
| - import_tasks: vanilla.yml | - ansible.builtin.import_tasks: vanilla.yml | ||||||
|   when: minecraft_eula |   when: minecraft_eula | ||||||
|  |  | ||||||
| - import_tasks: modpacks.yml | - ansible.builtin.import_tasks: modpacks.yml | ||||||
|   when: minecraft_eula |   when: minecraft_eula | ||||||
|  |  | ||||||
| - import_tasks: service.yml | - ansible.builtin.import_tasks: service.yml | ||||||
|   when: minecraft_eula |   when: minecraft_eula | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| - name: Download Minecraft modpack installer | - name: Download Minecraft modpack installer | ||||||
|   get_url: |   ansible.builtin.get_url: | ||||||
|     url: "{{ minecraft_modpack_url }}" |     url: "{{ minecraft_modpack_url }}" | ||||||
|     dest: "{{ minecraft_home }}/{{ item.name }}/serverinstall_{{ item.modpack | replace ('/', '_') }}" |     dest: "{{ minecraft_home }}/{{ item.name }}/serverinstall_{{ item.modpack | replace ('/', '_') }}" | ||||||
|     owner: "{{ minecraft_user }}" |     owner: "{{ minecraft_user }}" | ||||||
| @@ -9,7 +9,7 @@ | |||||||
|   when: item.modpack is defined and item.sha1 is not defined |   when: item.modpack is defined and item.sha1 is not defined | ||||||
|  |  | ||||||
| - name: Run Minecraft modpack installer | - 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: |   args: | ||||||
|     creates: "{{ minecraft_home }}/{{ item.name }}/mods" |     creates: "{{ minecraft_home }}/{{ item.name }}/mods" | ||||||
|     chdir: "{{ minecraft_home }}/{{ item.name }}" |     chdir: "{{ minecraft_home }}/{{ item.name }}" | ||||||
| @@ -17,7 +17,7 @@ | |||||||
|   when: item.modpack is defined and item.sha1 is not defined |   when: item.modpack is defined and item.sha1 is not defined | ||||||
|  |  | ||||||
| - name: Find Minecraft Forge | - name: Find Minecraft Forge | ||||||
|   find: |   ansible.builtin.find: | ||||||
|     paths: "{{ minecraft_home }}/{{ item.name }}" |     paths: "{{ minecraft_home }}/{{ item.name }}" | ||||||
|     patterns: "forge*.jar" |     patterns: "forge*.jar" | ||||||
|   register: minecraft_forge |   register: minecraft_forge | ||||||
| @@ -25,7 +25,7 @@ | |||||||
|   when: item.modpack is defined and item.sha1 is not defined |   when: item.modpack is defined and item.sha1 is not defined | ||||||
|  |  | ||||||
| - name: Link to Minecraft Forge | - name: Link to Minecraft Forge | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     src: "{{ item.files[0].path }}" |     src: "{{ item.files[0].path }}" | ||||||
|     dest: "{{ minecraft_home }}/{{ item.item.name }}/minecraft_server.jar" |     dest: "{{ minecraft_home }}/{{ item.item.name }}/minecraft_server.jar" | ||||||
|     owner: "{{ minecraft_user }}" |     owner: "{{ minecraft_user }}" | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| - name: Deploy Minecraft systemd service | - name: Deploy Minecraft systemd service | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: minecraft.service.j2 |     src: minecraft.service.j2 | ||||||
|     dest: "/etc/systemd/system/minecraft@.service" |     dest: "/etc/systemd/system/minecraft@.service" | ||||||
|   register: minecraft_systemd |   register: minecraft_systemd | ||||||
|  |  | ||||||
| - name: Deploy service environmental variables | - name: Deploy service environmental variables | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: environment.conf.j2 |     src: environment.conf.j2 | ||||||
|     dest: "{{ minecraft_home }}/{{ item.name }}/environment.conf" |     dest: "{{ minecraft_home }}/{{ item.name }}/environment.conf" | ||||||
|     owner: "{{ minecraft_user }}" |     owner: "{{ minecraft_user }}" | ||||||
| @@ -13,25 +13,25 @@ | |||||||
|   loop: "{{ minecraft }}" |   loop: "{{ minecraft }}" | ||||||
|  |  | ||||||
| - name: Reload systemd manager configuration | - name: Reload systemd manager configuration | ||||||
|   systemd: |   ansible.builtin.systemd: | ||||||
|     daemon_reload: true |     daemon_reload: true | ||||||
|   when: minecraft_systemd.changed |   when: minecraft_systemd.changed | ||||||
|  |  | ||||||
| - name: Disable non-default service instances | - name: Disable non-default service instances | ||||||
|   service: |   ansible.builtin.service: | ||||||
|     name: "minecraft@{{ item.name }}" |     name: "minecraft@{{ item.name }}" | ||||||
|     enabled: false |     enabled: false | ||||||
|   loop: "{{ minecraft }}" |   loop: "{{ minecraft }}" | ||||||
|   when: item.name != minecraft_onboot |   when: item.name != minecraft_onboot | ||||||
|  |  | ||||||
| - name: Enable default service instance | - name: Enable default service instance | ||||||
|   service: |   ansible.builtin.service: | ||||||
|     name: "minecraft@{{ minecraft_onboot }}" |     name: "minecraft@{{ minecraft_onboot }}" | ||||||
|     enabled: true |     enabled: true | ||||||
|   when: minecraft_eula and minecraft_onboot is defined |   when: minecraft_eula and minecraft_onboot is defined | ||||||
|  |  | ||||||
| - name: Run default service instance | - name: Run default service instance | ||||||
|   service: |   ansible.builtin.service: | ||||||
|     name: "minecraft@{{ minecraft_onboot }}" |     name: "minecraft@{{ minecraft_onboot }}" | ||||||
|     state: started |     state: started | ||||||
|   when: minecraft_eula and minecraft_onboot is defined and minecraft_onboot_run |   when: minecraft_eula and minecraft_onboot is defined and minecraft_onboot_run | ||||||
|   | |||||||
| @@ -1,16 +1,16 @@ | |||||||
| - name: Install Screen | - name: Install Screen | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: screen |     name: screen | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Create Minecraft user | - name: Create Minecraft user | ||||||
|   user: |   ansible.builtin.user: | ||||||
|     name: "{{ minecraft_user }}" |     name: "{{ minecraft_user }}" | ||||||
|     state: present |     state: present | ||||||
|     shell: /bin/bash |     ansible.builtin.shell: /bin/bash | ||||||
|  |  | ||||||
| - name: Create Minecraft directory | - name: Create Minecraft directory | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ minecraft_home }}/{{ item.name }}" |     path: "{{ minecraft_home }}/{{ item.name }}" | ||||||
|     state: directory |     state: directory | ||||||
|     owner: "{{ minecraft_user }}" |     owner: "{{ minecraft_user }}" | ||||||
| @@ -18,7 +18,7 @@ | |||||||
|   loop: "{{ minecraft }}" |   loop: "{{ minecraft }}" | ||||||
|  |  | ||||||
| - name: Answer to Mojang's EULA | - name: Answer to Mojang's EULA | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: eula.txt.j2 |     src: eula.txt.j2 | ||||||
|     dest: "{{ minecraft_home }}/{{ item.name }}/eula.txt" |     dest: "{{ minecraft_home }}/{{ item.name }}/eula.txt" | ||||||
|     owner: "{{ minecraft_user }}" |     owner: "{{ minecraft_user }}" | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| - name: Download Minecraft | - name: Download Minecraft | ||||||
|   get_url: |   ansible.builtin.get_url: | ||||||
|     url: "{{ minecraft_url }}" |     url: "{{ minecraft_url }}" | ||||||
|     dest: "{{ minecraft_home }}/{{ item.name }}/minecraft_server.jar" |     dest: "{{ minecraft_home }}/{{ item.name }}/minecraft_server.jar" | ||||||
|     checksum: "sha1:{{ item.sha1 }}" |     checksum: "sha1:{{ item.sha1 }}" | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| - name: Create Nextcloud network | - name: Create Nextcloud network | ||||||
|   docker_network: |   community.general.docker_network: | ||||||
|     name: "{{ nextcloud_container }}" |     name: "{{ nextcloud_container }}" | ||||||
|  |  | ||||||
| - name: Start Nextcloud's database container | - name: Start Nextcloud's database container | ||||||
|   docker_container: |   community.general.docker_container: | ||||||
|     name: "{{ nextcloud_dbcontainer }}" |     name: "{{ nextcloud_dbcontainer }}" | ||||||
|     image: mariadb:{{ nextcloud_dbversion }} |     image: mariadb:{{ nextcloud_dbversion }} | ||||||
|     state: started |     state: started | ||||||
| @@ -19,7 +19,7 @@ | |||||||
|       MYSQL_PASSWORD: "{{ nextcloud_dbpass }}" |       MYSQL_PASSWORD: "{{ nextcloud_dbpass }}" | ||||||
|  |  | ||||||
| - name: Start Nextcloud container | - name: Start Nextcloud container | ||||||
|   docker_container: |   community.general.docker_container: | ||||||
|     name: "{{ nextcloud_container }}" |     name: "{{ nextcloud_container }}" | ||||||
|     image: nextcloud:{{ nextcloud_version }} |     image: nextcloud:{{ nextcloud_version }} | ||||||
|     state: started |     state: started | ||||||
| @@ -29,6 +29,8 @@ | |||||||
|     networks: |     networks: | ||||||
|       - name: "{{ nextcloud_container }}" |       - name: "{{ nextcloud_container }}" | ||||||
|       - name: traefik |       - name: traefik | ||||||
|  |     env: | ||||||
|  |       PHP_MEMORY_LIMIT: 1024M | ||||||
|     labels: |     labels: | ||||||
|       traefik.http.routers.nextcloud.rule: "Host(`{{ nextcloud_domain }}`)" |       traefik.http.routers.nextcloud.rule: "Host(`{{ nextcloud_domain }}`)" | ||||||
|       traefik.http.routers.nextcloud.entrypoints: websecure |       traefik.http.routers.nextcloud.entrypoints: websecure | ||||||
| @@ -41,34 +43,34 @@ | |||||||
|       traefik.enable: "true" |       traefik.enable: "true" | ||||||
|  |  | ||||||
| - name: Grab Nextcloud database container information | - name: Grab Nextcloud database container information | ||||||
|   docker_container_info: |   community.general.docker_container_info: | ||||||
|     name: "{{ nextcloud_dbcontainer }}" |     name: "{{ nextcloud_dbcontainer }}" | ||||||
|   register: nextcloud_dbinfo |   register: nextcloud_dbinfo | ||||||
|  |  | ||||||
| - name: Grab Nextcloud container information | - name: Grab Nextcloud container information | ||||||
|   docker_container_info: |   community.general.docker_container_info: | ||||||
|     name: "{{ nextcloud_container }}" |     name: "{{ nextcloud_container }}" | ||||||
|   register: nextcloud_info |   register: nextcloud_info | ||||||
|  |  | ||||||
| - name: Wait for Nextcloud to become available | - name: Wait for Nextcloud to become available | ||||||
|   wait_for: |   ansible.builtin.wait_for: | ||||||
|     host: "{{ nextcloud_info.container.NetworkSettings.Networks.traefik.IPAddress }}" |     host: "{{ nextcloud_info.container.NetworkSettings.Networks.traefik.IPAddress }}" | ||||||
|     port: 80 |     port: 80 | ||||||
|  |  | ||||||
| - name: Check Nextcloud status | - 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" |             php occ status" | ||||||
|   register: nextcloud_status |   register: nextcloud_status | ||||||
|   args: |   args: | ||||||
|     removes: "{{ nextcloud_root }}/config/CAN_INSTALL" |     removes: "{{ nextcloud_root }}/config/CAN_INSTALL" | ||||||
|  |  | ||||||
| - name: Wait for Nextcloud database to become available | - name: Wait for Nextcloud database to become available | ||||||
|   wait_for: |   ansible.builtin.wait_for: | ||||||
|     host: "{{ nextcloud_dbinfo.container.NetworkSettings.Networks.nextcloud.IPAddress }}" |     host: "{{ nextcloud_dbinfo.container.NetworkSettings.Networks.nextcloud.IPAddress }}" | ||||||
|     port: 3306 |     port: 3306 | ||||||
|  |  | ||||||
| - name: Install Nextcloud | - 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 |             php occ maintenance:install | ||||||
|               --database "mysql" |               --database "mysql" | ||||||
|               --database-host "{{ nextcloud_dbcontainer }}" |               --database-host "{{ nextcloud_dbcontainer }}" | ||||||
| @@ -83,19 +85,19 @@ | |||||||
|     - nextcloud_domain is defined |     - nextcloud_domain is defined | ||||||
|  |  | ||||||
| - name: Set Nextcloud's Trusted Proxy | - 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 |             php occ config:system:set trusted_proxies 0 | ||||||
|               --value="{{ traefik_name }}"' |               --value="{{ traefik_name }}"' | ||||||
|   when: nextcloud_install.changed |   when: nextcloud_install.changed | ||||||
|  |  | ||||||
| - name: Set Nextcloud's Trusted Domain | - 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 |             php occ config:system:set trusted_domains 0 | ||||||
|               --value="{{ nextcloud_domain }}"' |               --value="{{ nextcloud_domain }}"' | ||||||
|   when: nextcloud_install.changed |   when: nextcloud_install.changed | ||||||
|  |  | ||||||
| - name: Preform Nextcloud database maintenance | - 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: |   loop: | ||||||
|     - "php occ maintenance:mode --on" |     - "php occ maintenance:mode --on" | ||||||
|     - "php occ db:add-missing-indices" |     - "php occ db:add-missing-indices" | ||||||
| @@ -103,7 +105,14 @@ | |||||||
|     - "php occ maintenance:mode --off" |     - "php occ maintenance:mode --off" | ||||||
|   when: nextcloud_install.changed |   when: nextcloud_install.changed | ||||||
|  |  | ||||||
|  | - name: Install Nextcloud background jobs cron | ||||||
|  |   ansible.builtin.cron: | ||||||
|  |     name: Nextcloud background job | ||||||
|  |     minute: "*/5" | ||||||
|  |     job: "/usr/bin/docker exec -u www-data nextcloud /usr/local/bin/php -f /var/www/html/cron.php" | ||||||
|  |     user: root | ||||||
|  |  | ||||||
| - name: Remove Nextcloud's CAN_INSTALL file | - name: Remove Nextcloud's CAN_INSTALL file | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ nextcloud_root }}/config/CAN_INSTALL" |     path: "{{ nextcloud_root }}/config/CAN_INSTALL" | ||||||
|     state: absent |     state: absent | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								roles/postgresql/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								roles/postgresql/defaults/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | postgresql_config: /etc/postgresql/13/main/pg_hba.conf | ||||||
|  | postgresql_listen: "*" | ||||||
|  | postgresql_trust: | ||||||
|  |   - "172.16.0.0/12" | ||||||
|  |   - "192.168.0.0/16" | ||||||
							
								
								
									
										43
									
								
								roles/postgresql/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								roles/postgresql/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | - name: Install PostgreSQL | ||||||
|  |   ansible.builtin.apt: | ||||||
|  |     name: postgresql | ||||||
|  |     state: present | ||||||
|  |  | ||||||
|  | - name: Trust connections to PostgreSQL | ||||||
|  |   community.general.postgresql_pg_hba: | ||||||
|  |     dest: "{{ postgresql_config }}" | ||||||
|  |     contype: host | ||||||
|  |     databases: all | ||||||
|  |     users: all | ||||||
|  |     address: "{{ item }}" | ||||||
|  |     method: trust | ||||||
|  |   register: postgresql_hba | ||||||
|  |   loop: "{{ postgresql_trust }}" | ||||||
|  |  | ||||||
|  | - name: Change PostgreSQL listen addresses | ||||||
|  |   community.general.postgresql_set: | ||||||
|  |     name: listen_addresses | ||||||
|  |     value: "{{ postgresql_listen }}" | ||||||
|  |   become: true | ||||||
|  |   become_user: postgres | ||||||
|  |   register: postgresql_config | ||||||
|  |  | ||||||
|  | - name: Reload PostgreSQL | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: postgresql | ||||||
|  |     state: reloaded | ||||||
|  |   when: postgresql_hba.changed and not postgresql_config.changed | ||||||
|  |  | ||||||
|  | - name: Restart PostgreSQL | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: postgresql | ||||||
|  |     state: restarted | ||||||
|  |   when: postgresql_config.changed | ||||||
|  |  | ||||||
|  | - name: Allow database connections | ||||||
|  |   community.general.ufw: | ||||||
|  |     rule: allow | ||||||
|  |     port: "5432" | ||||||
|  |     proto: tcp | ||||||
|  |     src: "{{ item }}" | ||||||
|  |   loop: "{{ postgresql_trust }}" | ||||||
| @@ -1,35 +1,35 @@ | |||||||
| - name: Install Prometheus node exporter | - name: Install Prometheus node exporter | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: prometheus-node-exporter |     name: prometheus-node-exporter | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Run Prometheus node exporter | - name: Run Prometheus node exporter | ||||||
|   service: |   ansible.builtin.service: | ||||||
|     name: prometheus-node-exporter |     name: prometheus-node-exporter | ||||||
|     state: started |     state: started | ||||||
|  |  | ||||||
| - name: Create Prometheus data directory | - name: Create Prometheus data directory | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ prom_root }}/prometheus" |     path: "{{ prom_root }}/prometheus" | ||||||
|     state: directory |     state: directory | ||||||
|     owner: nobody |     owner: nobody | ||||||
|  |  | ||||||
| - name: Create Prometheus config directory | - name: Create Prometheus config directory | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ prom_root }}/config" |     path: "{{ prom_root }}/config" | ||||||
|     state: directory |     state: directory | ||||||
|  |  | ||||||
| - name: Install Prometheus configuration | - name: Install Prometheus configuration | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: prometheus.yml.j2 |     src: prometheus.yml.j2 | ||||||
|     dest: "{{ prom_root }}/config/prometheus.yml" |     dest: "{{ prom_root }}/config/prometheus.yml" | ||||||
|  |  | ||||||
| - name: Create Prometheus network | - name: Create Prometheus network | ||||||
|   docker_network: |   community.general.docker_network: | ||||||
|     name: "{{ prom_name }}" |     name: "{{ prom_name }}" | ||||||
|  |  | ||||||
| - name: Start Prometheus container | - name: Start Prometheus container | ||||||
|   docker_container: |   community.general.docker_container: | ||||||
|     name: "{{ prom_name }}" |     name: "{{ prom_name }}" | ||||||
|     image: prom/prometheus:{{ prom_version }} |     image: prom/prometheus:{{ prom_version }} | ||||||
|     state: started |     state: started | ||||||
| @@ -51,7 +51,7 @@ | |||||||
|       traefik.enable: "true" |       traefik.enable: "true" | ||||||
|  |  | ||||||
| - name: Start Grafana container | - name: Start Grafana container | ||||||
|   docker_container: |   community.general.docker_container: | ||||||
|     name: "{{ grafana_name }}" |     name: "{{ grafana_name }}" | ||||||
|     image: grafana/grafana:{{ grafana_version }} |     image: grafana/grafana:{{ grafana_version }} | ||||||
|     state: started |     state: started | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								roles/proxy/files/reload-nginx.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								roles/proxy/files/reload-nginx.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | systemctl reload nginx | ||||||
							
								
								
									
										5
									
								
								roles/proxy/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								roles/proxy/handlers/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | - name: Reload nginx | ||||||
|  |   ansible.builtin.service: | ||||||
|  |     name: nginx | ||||||
|  |     state: reloaded | ||||||
|  |   listen: reload_nginx | ||||||
							
								
								
									
										104
									
								
								roles/proxy/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								roles/proxy/tasks/main.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | |||||||
|  | - name: Install nginx | ||||||
|  |   ansible.builtin.apt: | ||||||
|  |     name: nginx | ||||||
|  |     state: present | ||||||
|  |     update_cache: true | ||||||
|  |  | ||||||
|  | - name: Start nginx and enable on boot | ||||||
|  |   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 | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: nginx.conf.j2 | ||||||
|  |     dest: /etc/nginx/nginx.conf | ||||||
|  |     mode: 0644 | ||||||
|  |   notify: reload_nginx | ||||||
|  |  | ||||||
|  | - name: Install nginx sites configuration | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: server-nginx.conf.j2 | ||||||
|  |     dest: "/etc/nginx/sites-available/{{ item.domain }}.conf" | ||||||
|  |     mode: 0400 | ||||||
|  |   loop: "{{ proxy.servers }}" | ||||||
|  |   notify: reload_nginx | ||||||
|  |   register: nginx_sites | ||||||
|  |  | ||||||
|  | - name: Enable nginx sites configuration | ||||||
|  |   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 | ||||||
|  |   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' | ||||||
|  |   args: | ||||||
|  |     creates: /etc/ssl/certs/nginx-selfsigned.crt | ||||||
|  |   when: proxy.production is not defined or not proxy.production | ||||||
|  |   notify: reload_nginx | ||||||
|  |  | ||||||
|  | - name: Install LE's certbot | ||||||
|  |   ansible.builtin.apt: | ||||||
|  |     name: ['certbot', 'python3-certbot-dns-cloudflare'] | ||||||
|  |     state: present | ||||||
|  |   when: proxy.production is defined and proxy.production | ||||||
|  |  | ||||||
|  | - name: Install Cloudflare API token | ||||||
|  |   ansible.builtin.template: | ||||||
|  |     src: cloudflare.ini.j2 | ||||||
|  |     dest: /root/.cloudflare.ini | ||||||
|  |     mode: 0400 | ||||||
|  |   when: proxy.production is defined and proxy.production and proxy.dns_cloudflare is defined | ||||||
|  |  | ||||||
|  | - name: Create nginx post renewal hook directory | ||||||
|  |   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 | ||||||
|  |   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 | ||||||
|  |   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 }}" \ | ||||||
|  |             -d "{{ item }}" \ | ||||||
|  |             {{ proxy.dns_cloudflare.opts | default("") }}' | ||||||
|  |   args: | ||||||
|  |     creates: "/etc/letsencrypt/live/{{ item }}/fullchain.pem" | ||||||
|  |   loop: "{{ proxy.dns_cloudflare.wildcard_domains }}" | ||||||
|  |   when: proxy.production is defined and proxy.production and proxy.dns_cloudflare is defined | ||||||
|  |   notify: reload_nginx | ||||||
|  |  | ||||||
|  | - name: Add HTTP and HTTPS firewall rule | ||||||
|  |   community.general.ufw: | ||||||
|  |     rule: allow | ||||||
|  |     port: "{{ item }}" | ||||||
|  |     proto: tcp | ||||||
|  |   loop: | ||||||
|  |     - "80" | ||||||
|  |     - "443" | ||||||
							
								
								
									
										2
									
								
								roles/proxy/templates/cloudflare.ini.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								roles/proxy/templates/cloudflare.ini.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | # Cloudflare API token used by Certbot | ||||||
|  | dns_cloudflare_api_token = {{ proxy.dns_cloudflare.api_token }} | ||||||
							
								
								
									
										34
									
								
								roles/proxy/templates/nginx.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								roles/proxy/templates/nginx.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | user www-data; | ||||||
|  | worker_processes auto; | ||||||
|  | error_log /var/log/nginx/error.log; | ||||||
|  | pid /run/nginx.pid; | ||||||
|  | include /etc/nginx/modules-enabled/*.conf; | ||||||
|  |  | ||||||
|  | events { | ||||||
|  |   worker_connections 1024; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | http { | ||||||
|  |   include           /etc/nginx/mime.types; | ||||||
|  |   default_type      application/octet-stream; | ||||||
|  |   log_format        main '$remote_addr - $remote_user [$time_local]  $status ' | ||||||
|  |                          '"$request" $body_bytes_sent "$http_referer" ' | ||||||
|  |                          '"$http_user_agent" "$http_x_forwarded_for"'; | ||||||
|  |   access_log        /var/log/nginx/access.log  main; | ||||||
|  |   server_tokens     off; | ||||||
|  |   sendfile          on; | ||||||
|  |   tcp_nopush        on; | ||||||
|  |   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/*; | ||||||
|  | } | ||||||
							
								
								
									
										57
									
								
								roles/proxy/templates/server-nginx.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								roles/proxy/templates/server-nginx.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | server { | ||||||
|  |   listen 80; | ||||||
|  |   listen [::]:80; | ||||||
|  |   server_name {{ item.domain }}; | ||||||
|  |   return 301 https://{{ item.domain }}$request_uri; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | server { | ||||||
|  |   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 %} | ||||||
|  | {% for wildcard in proxy.dns_cloudflare.wildcard_domains %} | ||||||
|  | {% set domain_regex = '^\*\.' + wildcard + '$' %} | ||||||
|  | {% if item.domain | regex_search(wildcard) %} | ||||||
|  |   ssl_certificate     /etc/letsencrypt/live/{{ wildcard }}/fullchain.pem; | ||||||
|  |   ssl_certificate_key /etc/letsencrypt/live/{{ wildcard }}/privkey.pem; | ||||||
|  | {% endif %} | ||||||
|  | {% endfor %} | ||||||
|  | {% elif proxy.production is defined and proxy.production and item.tls.cert is not defined %} | ||||||
|  |   ssl_certificate     /etc/letsencrypt/live/{{ item.domain }}/fullchain.pem; | ||||||
|  |   ssl_certificate_key /etc/letsencrypt/live/{{ item.domain }}/privkey.pem; | ||||||
|  | {% elif proxy.production is defined and proxy.production and item.tls.cert is defined %} | ||||||
|  |   ssl_certificate     {{ item.tls.cert }}; | ||||||
|  |   ssl_certificate_key {{ item.tls.key }}; | ||||||
|  | {% 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; | ||||||
|  |     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||||
|  |     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/>. | # along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
| - name: Install rsnapshot | - name: Install rsnapshot | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: rsnapshot |     name: rsnapshot | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Create rsnapshot system directories | - name: Create rsnapshot system directories | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ item }}" |     path: "{{ item }}" | ||||||
|     state: directory |     state: directory | ||||||
|   loop: |   loop: | ||||||
| @@ -26,19 +26,19 @@ | |||||||
|     - "{{ rsnapshot_logdir }}" |     - "{{ rsnapshot_logdir }}" | ||||||
|  |  | ||||||
| - name: Create snapshot_root directories | - name: Create snapshot_root directories | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ item.root | default(rsnapshot_root) }}" |     path: "{{ item.root | default(rsnapshot_root) }}" | ||||||
|     state: directory |     state: directory | ||||||
|   loop: "{{ rsnapshot }}" |   loop: "{{ rsnapshot }}" | ||||||
|  |  | ||||||
| - name: Install rsnapshot configuration | - name: Install rsnapshot configuration | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: rsnapshot.conf.j2 |     src: rsnapshot.conf.j2 | ||||||
|     dest: "{{ rsnapshot_confdir }}/{{ item.name }}.conf" |     dest: "{{ rsnapshot_confdir }}/{{ item.name }}.conf" | ||||||
|   loop: "{{ rsnapshot }}" |   loop: "{{ rsnapshot }}" | ||||||
|  |  | ||||||
| - name: Install rsnapshot crons | - name: Install rsnapshot crons | ||||||
|   cron: |   ansible.builtin.cron: | ||||||
|     name: "{{ item.1.interval }} rsnapshot of {{ item.0.name }}" |     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" |     job: "/usr/bin/rsnapshot -c {{ rsnapshot_confdir }}/{{ item.0.name }}.conf {{ item.1.interval }} >/dev/null" | ||||||
|     user: "root" |     user: "root" | ||||||
| @@ -53,13 +53,13 @@ | |||||||
|     - cron |     - cron | ||||||
|  |  | ||||||
| - name: Install rsnapshot report script | - name: Install rsnapshot report script | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: rsnapshot-report.sh.j2 |     src: rsnapshot-report.sh.j2 | ||||||
|     dest: /usr/local/bin/rsnapshot-report |     dest: /usr/local/bin/rsnapshot-report | ||||||
|     mode: '0750' |     mode: '0750' | ||||||
|  |  | ||||||
| - name: Install rsnapshot report crons | - name: Install rsnapshot report crons | ||||||
|   cron: |   ansible.builtin.cron: | ||||||
|     name: "{{ item.name }} rsnapshot report email" |     name: "{{ item.name }} rsnapshot report email" | ||||||
|     job: "/usr/local/bin/rsnapshot-report {{ rsnapshot_reportlog }} |     job: "/usr/local/bin/rsnapshot-report {{ rsnapshot_reportlog }} | ||||||
|           | mail -s '{{ item.report.subject | default('Backup Report') }}' {{ item.report.to }}" |           | mail -s '{{ item.report.subject | default('Backup Report') }}' {{ item.report.to }}" | ||||||
|   | |||||||
| @@ -1,15 +1,15 @@ | |||||||
| - name: Create nginx root | - name: Create nginx root | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ nginx_root }}" |     path: "{{ nginx_root }}" | ||||||
|     state: directory |     state: directory | ||||||
| 
 | 
 | ||||||
| - name: Generate deploy keys | - name: Generate deploy keys | ||||||
|   openssh_keypair: |   community.crypto.openssh_keypair: | ||||||
|     path: "{{ nginx_repo_key }}" |     path: "{{ nginx_repo_key }}" | ||||||
|     state: present |     state: present | ||||||
| 
 | 
 | ||||||
| - name: Clone static website files | - name: Clone static website files | ||||||
|   git: |   ansible.builtin.git: | ||||||
|     repo: "{{ nginx_repo_url }}" |     repo: "{{ nginx_repo_url }}" | ||||||
|     dest: "{{ nginx_html }}" |     dest: "{{ nginx_html }}" | ||||||
|     version: "{{ nginx_repo_branch }}" |     version: "{{ nginx_repo_branch }}" | ||||||
| @@ -17,7 +17,7 @@ | |||||||
|     separate_git_dir: "{{ nginx_repo_dest }}" |     separate_git_dir: "{{ nginx_repo_dest }}" | ||||||
| 
 | 
 | ||||||
| - name: Start nginx container | - name: Start nginx container | ||||||
|   docker_container: |   community.general.docker_container: | ||||||
|     name: "{{ nginx_name }}" |     name: "{{ nginx_name }}" | ||||||
|     image: nginx:{{ nginx_version }} |     image: nginx:{{ nginx_version }} | ||||||
|     state: started |     state: started | ||||||
| @@ -29,9 +29,9 @@ | |||||||
|       - "{{ nginx_html }}:/usr/share/nginx/html:ro" |       - "{{ nginx_html }}:/usr/share/nginx/html:ro" | ||||||
|     labels: |     labels: | ||||||
|       traefik.http.routers.nginx.rule: "Host(`{{ nginx_domain }}`)" |       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.entrypoints: websecure | ||||||
|       traefik.http.routers.nginx.tls.certresolver: letsencrypt |       #traefik.http.routers.nginx.tls.certresolver: letsencrypt | ||||||
|       traefik.http.routers.nginx.middlewares: "securehttps@file,nginxauth" |       #traefik.http.routers.nginx.middlewares: "securehttps@file,nginxauth" | ||||||
|       traefik.docker.network: traefik |       traefik.docker.network: traefik | ||||||
|       traefik.enable: "true" |       traefik.enable: "true" | ||||||
| @@ -1,10 +1,18 @@ | |||||||
|  | # Container settings | ||||||
| traefik_name: traefik | traefik_name: traefik | ||||||
| traefik_dashboard: false | traefik_standalone: true | ||||||
| traefik_root: "/opt/{{ traefik_name }}" | 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" | 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_production: false | ||||||
|  | traefik_hsts_enable: false | ||||||
| traefik_hsts_preload: false | traefik_hsts_preload: false | ||||||
| traefik_hsts_seconds: 0 | traefik_hsts_seconds: 0 | ||||||
| traefik_ports: | traefik_http_redirect: true | ||||||
|   - "80:80" |  | ||||||
|   - "443:443" | # Host settings | ||||||
|  | traefik_root: "{{ docker_compose_root }}/{{ traefik_name }}" | ||||||
|   | |||||||
| @@ -1,13 +1,12 @@ | |||||||
| - name: Reload Traefik container | - name: Reload Traefik container | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ traefik_root }}/config/dynamic" |     path: "{{ traefik_root }}/config/dynamic" | ||||||
|     state: touch |     state: touch | ||||||
|  |     mode: 0500 | ||||||
|   listen: reload_traefik |   listen: reload_traefik | ||||||
|  |  | ||||||
| - name: Restart Traefik container | - name: Restart Traefik | ||||||
|   docker_container: |   ansible.builtin.service: | ||||||
|     name: "{{ traefik_name }}" |     name: "{{ docker_compose_service }}@{{ traefik_name }}" | ||||||
|     image: traefik:{{ traefik_version }} |     state: restarted | ||||||
|     state: started |  | ||||||
|     restart: yes |  | ||||||
|   listen: restart_traefik |   listen: restart_traefik | ||||||
|   | |||||||
| @@ -1,55 +1,49 @@ | |||||||
| - name: Create Traefik configuration directories | - name: Create Traefik directories | ||||||
|   file: |   ansible.builtin.file: | ||||||
|     path: "{{ traefik_root }}/config/dynamic" |     path: "{{ traefik_root }}/config/dynamic" | ||||||
|  |     mode: 0500 | ||||||
|     state: directory |     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 | - name: Install dynamic security configuration | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: security.yml.j2 |     src: security.yml.j2 | ||||||
|     dest: "{{ traefik_root }}/config/dynamic/security.yml" |     dest: "{{ traefik_root }}/config/dynamic/security.yml" | ||||||
|     owner: root |     owner: root | ||||||
|     group: root |     group: root | ||||||
|     mode: 0600 |     mode: 0400 | ||||||
|   notify: reload_traefik |   notify: reload_traefik | ||||||
|  |  | ||||||
| - name: Install dynamic non-docker configuration | - name: Install dynamic non-docker configuration | ||||||
|   template: |   ansible.builtin.template: | ||||||
|     src: "external.yml.j2" |     src: "external.yml.j2" | ||||||
|     dest: "{{ traefik_root }}/config/dynamic/{{ item.name }}.yml" |     dest: "{{ traefik_root }}/config/dynamic/{{ item.name }}.yml" | ||||||
|  |     mode: 0400 | ||||||
|   loop: "{{ traefik_external }}" |   loop: "{{ traefik_external }}" | ||||||
|   when: traefik_external is defined |   when: traefik_external is defined | ||||||
|  |  | ||||||
| - name: Create Traefik network | - name: Install Traefik's docker-compose file | ||||||
|   docker_network: |   ansible.builtin.template: | ||||||
|     name: traefik |     src: docker-compose.yml.j2 | ||||||
|  |     dest: "{{ traefik_root }}/docker-compose.yml" | ||||||
|  |     mode: 0400 | ||||||
|  |   notify: restart_traefik | ||||||
|  |  | ||||||
| - name: Start Traefik container | - name: Install Traefik's docker-compose variables | ||||||
|   docker_container: |   ansible.builtin.template: | ||||||
|     name: "{{ traefik_name }}" |     src: compose-env.j2 | ||||||
|     image: traefik:{{ traefik_version }} |     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 |     state: started | ||||||
|     restart_policy: always |     enabled: true | ||||||
|     ports: "{{ traefik_ports }}" |  | ||||||
|     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" |  | ||||||
|   | |||||||
							
								
								
									
										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 %} | {% elif item.middlewares is defined %} | ||||||
|       middlewares: "{{ item.middlewares }}" |       middlewares: "{{ item.middlewares }}" | ||||||
| {% endif %} | {% endif %} | ||||||
|  | {% if traefik_acme_email is defined %} | ||||||
|       tls: |       tls: | ||||||
|         certResolver: letsencrypt |         certResolver: letsencrypt | ||||||
|         domains: |         domains: | ||||||
|           - main: "{{ item.domain }}" |           - main: "{{ item.domain }}" | ||||||
|  | {% endif %} | ||||||
|       entryPoints: |       entryPoints: | ||||||
|         - "websecure" |         - "websecure" | ||||||
|   services: |   services: | ||||||
|   | |||||||
| @@ -11,6 +11,8 @@ http: | |||||||
|         sslRedirect: true |         sslRedirect: true | ||||||
|         browserXssFilter: true |         browserXssFilter: true | ||||||
|         contentTypeNosniff: true |         contentTypeNosniff: true | ||||||
|  | {% if traefik_hsts_enable is defined and traefik_hsts_enable %} | ||||||
|         stsPreload: {{ traefik_hsts_preload }} |         stsPreload: {{ traefik_hsts_preload }} | ||||||
|         stsSeconds: {{ traefik_hsts_seconds }} |         stsSeconds: {{ traefik_hsts_seconds }} | ||||||
|  | {% endif %} | ||||||
|         customFrameOptionsValue: SAMEORIGIN |         customFrameOptionsValue: SAMEORIGIN | ||||||
|   | |||||||
| @@ -10,16 +10,20 @@ providers: | |||||||
| entrypoints: | entrypoints: | ||||||
|   web: |   web: | ||||||
|     address: ':80' |     address: ':80' | ||||||
|  | {% if traefik_http_redirect is defined and traefik_http_redirect and not traefik_http_only %} | ||||||
|     http: |     http: | ||||||
|       redirections: |       redirections: | ||||||
|         entrypoint: |         entrypoint: | ||||||
|           to: websecure |           to: websecure | ||||||
|           scheme: https |           scheme: https | ||||||
|           permanent: true |           permanent: true | ||||||
|  | {% endif %} | ||||||
|  | {% if not traefik_http_only is defined or not traefik_http_only %} | ||||||
|   websecure: |   websecure: | ||||||
|     address: ':443' |     address: ':443' | ||||||
|     http: |     http: | ||||||
|       tls: {} |       tls: {} | ||||||
|  | {% endif %} | ||||||
|  |  | ||||||
| {% if traefik_acme_email is defined %} | {% if traefik_acme_email is defined %} | ||||||
| certificatesResolvers: | certificatesResolvers: | ||||||
|   | |||||||
| @@ -1,52 +1,52 @@ | |||||||
| - name: Install GnuPG | - name: Install GnuPG | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: gnupg |     name: gnupg | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Add AdoptOpenJDK's signing key | - name: Add AdoptOpenJDK's signing key | ||||||
|   apt_key: |   ansible.builtin.apt_key: | ||||||
|     id: 8ED17AF5D7E675EB3EE3BCE98AC3B29174885C03 |     id: 8ED17AF5D7E675EB3EE3BCE98AC3B29174885C03 | ||||||
|     url: https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public |     url: https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | ||||||
|  |  | ||||||
| - name: Add MongoDB 3.6's signing key | - name: Add MongoDB 3.6's signing key | ||||||
|   apt_key: |   ansible.builtin.apt_key: | ||||||
|     id: 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5 |     id: 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5 | ||||||
|     url: https://www.mongodb.org/static/pgp/server-3.6.asc |     url: https://www.mongodb.org/static/pgp/server-3.6.asc | ||||||
|  |  | ||||||
| - name: Add UniFi's signing key | - name: Add UniFi's signing key | ||||||
|   apt_key: |   ansible.builtin.apt_key: | ||||||
|     id: 4A228B2D358A5094178285BE06E85760C0A52C50 |     id: 4A228B2D358A5094178285BE06E85760C0A52C50 | ||||||
|     keyserver: keyserver.ubuntu.com |     keyserver: keyserver.ubuntu.com | ||||||
|  |  | ||||||
| - name: Install AdoptOpenJDK repository | - name: Install AdoptOpenJDK repository | ||||||
|   apt_repository: |   ansible.builtin.apt_repository: | ||||||
|     repo: deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main |     repo: deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main | ||||||
|     mode: 0644 |     mode: 0644 | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Install MongoDB 3.6 repository | - 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 |     repo: deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/3.6 main | ||||||
|     mode: 0644 |     mode: 0644 | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Install UniFi repository | - name: Install UniFi repository | ||||||
|   apt_repository: |   ansible.builtin.apt_repository: | ||||||
|     repo: deb https://www.ui.com/downloads/unifi/debian stable ubiquiti |     repo: deb https://www.ui.com/downloads/unifi/debian stable ubiquiti | ||||||
|     mode: 0644 |     mode: 0644 | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Install MongoDB 3.6 | - name: Install MongoDB 3.6 | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: mongodb-org |     name: mongodb-org | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Install OpenJDK 8 LTS | - name: Install OpenJDK 8 LTS | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: adoptopenjdk-8-hotspot |     name: adoptopenjdk-8-hotspot | ||||||
|     state: present |     state: present | ||||||
|  |  | ||||||
| - name: Install UniFi | - name: Install UniFi | ||||||
|   apt: |   ansible.builtin.apt: | ||||||
|     name: unifi |     name: unifi | ||||||
|     state: present |     state: present | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| - name: Start WordPress database container | - name: Start WordPress database container | ||||||
|   docker_container: |   community.general.docker_container: | ||||||
|     name: "{{ wordpress_dbcontainer }}" |     name: "{{ wordpress_dbcontainer }}" | ||||||
|     image: mariadb:{{ wordpress_dbversion }} |     image: mariadb:{{ wordpress_dbversion }} | ||||||
|     restart_policy: always |     restart_policy: always | ||||||
| @@ -11,7 +11,7 @@ | |||||||
|       MYSQL_PASSWORD: "{{ wordpress_dbpass }}" |       MYSQL_PASSWORD: "{{ wordpress_dbpass }}" | ||||||
|  |  | ||||||
| - name: Start WordPress container | - name: Start WordPress container | ||||||
|   docker_container: |   community.general.docker_container: | ||||||
|     name: "{{ wordpress_container }}" |     name: "{{ wordpress_container }}" | ||||||
|     image: wordpress:{{ wordpress_version }} |     image: wordpress:{{ wordpress_version }} | ||||||
|     restart_policy: always |     restart_policy: always | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ HOST[8]="wordpress.${DOMAIN}" | |||||||
| HOST[9]="site1.wordpress.${DOMAIN}" | HOST[9]="site1.wordpress.${DOMAIN}" | ||||||
| HOST[10]="site2.wordpress.${DOMAIN}" | HOST[10]="site2.wordpress.${DOMAIN}" | ||||||
| HOST[11]="unifi.${DOMAIN}" | HOST[11]="unifi.${DOMAIN}" | ||||||
|  | HOST[12]="jellyfin.${DOMAIN}" | ||||||
|  |  | ||||||
| # Get Vagrantbox guest IP | # Get Vagrantbox guest IP | ||||||
| VAGRANT_OUTPUT=$(vagrant ssh -c "hostname -I | cut -d' ' -f2" 2>/dev/null) | VAGRANT_OUTPUT=$(vagrant ssh -c "hostname -I | cut -d' ' -f2" 2>/dev/null) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user