From 12444311a4780c50a2625af434dd9d230a68ed5f Mon Sep 17 00:00:00 2001 From: Matthew McKinnon Date: Mon, 8 Sep 2025 18:29:40 +1000 Subject: [PATCH] Initial Commit --- .gitea/ISSUE_TEMPLATE/adding.yml | 74 +++++++ .gitea/ISSUE_TEMPLATE/feature-request.yml | 50 +++++ .gitea/workflows/deploy-containers.yml | 30 +++ .gitea/workflows/deploy.sh | 13 ++ README.md | 175 +++++++++++++++++ ansible.cfg | 6 + build-debian-promox-template.yml | 78 ++++++++ frigate.yml | 10 + group_vars/all.yml | 124 ++++++++++++ group_vars/all.yml-templace | 82 ++++++++ hosts | 18 ++ main.yml | 191 ++++++++++++++++++ renovate.json | 18 ++ roles/docker/defaults/main.yml | 2 + roles/docker/meta/main.yml | 52 +++++ roles/docker/tasks/main.yml | 49 +++++ roles/docker/vars/main.yml | 51 +++++ roles/docker/vars/main.yml-template | 21 ++ roles/nfs/defaults/main.yml | 8 + roles/nfs/meta/main.yml | 52 +++++ roles/nfs/tasks/main.yml | 20 ++ roles/traefik/defaults/main.yml | 2 + roles/traefik/meta/main.yml | 52 +++++ roles/traefik/tasks/main.yml | 95 +++++++++ roles/traefik/templates/config.yml.j2 | 51 +++++ roles/traefik/templates/traefik.yml.j2 | 42 ++++ roles/traefik/vars/main.yml | 14 ++ roles/traefik/vars/main.yml-template | 5 + scripts/notify.sh.j2 | 2 + scripts/rclone.conf | 196 +++++++++++++++++++ tasks/base.yml | 224 ++++++++++++++++++++++ tasks/comprofix.com.yml | 14 ++ tasks/dozzle-agent.yml | 12 ++ tasks/dozzle.yml | 29 +++ tasks/gitea-runner-homelab.yml | 42 ++++ tasks/gitea.yml | 134 +++++++++++++ tasks/gotify.yml | 26 +++ tasks/homepage.yml | 40 ++++ tasks/idrac.yml | 15 ++ tasks/invoiceninja.yml | 95 +++++++++ tasks/iscsi.yml | 88 +++++++++ tasks/jellyseerr.yml | 29 +++ tasks/lidarr.yml | 36 ++++ tasks/mariadb.yml | 29 +++ tasks/mealie.yml | 36 ++++ tasks/mediawiki.yml | 29 +++ tasks/omada.yml | 24 +++ tasks/osticket.yml | 61 ++++++ tasks/postgres.yml | 22 +++ tasks/prowlarr.yml | 31 +++ tasks/pykms.yml | 26 +++ tasks/radarr.yml | 31 +++ tasks/readarr.yml | 33 ++++ tasks/sabnzbd.yml | 32 ++++ tasks/sonarr.yml | 31 +++ tasks/speedtest.yml | 41 ++++ tasks/traggo.yml | 26 +++ tasks/vaultwarden.yml | 64 +++++++ vault.sh | 48 +++++ 59 files changed, 2931 insertions(+) create mode 100644 .gitea/ISSUE_TEMPLATE/adding.yml create mode 100644 .gitea/ISSUE_TEMPLATE/feature-request.yml create mode 100644 .gitea/workflows/deploy-containers.yml create mode 100755 .gitea/workflows/deploy.sh create mode 100644 README.md create mode 100644 ansible.cfg create mode 100644 build-debian-promox-template.yml create mode 100644 frigate.yml create mode 100644 group_vars/all.yml create mode 100644 group_vars/all.yml-templace create mode 100644 hosts create mode 100644 main.yml create mode 100644 renovate.json create mode 100644 roles/docker/defaults/main.yml create mode 100644 roles/docker/meta/main.yml create mode 100644 roles/docker/tasks/main.yml create mode 100644 roles/docker/vars/main.yml create mode 100644 roles/docker/vars/main.yml-template create mode 100644 roles/nfs/defaults/main.yml create mode 100644 roles/nfs/meta/main.yml create mode 100644 roles/nfs/tasks/main.yml create mode 100644 roles/traefik/defaults/main.yml create mode 100644 roles/traefik/meta/main.yml create mode 100644 roles/traefik/tasks/main.yml create mode 100644 roles/traefik/templates/config.yml.j2 create mode 100644 roles/traefik/templates/traefik.yml.j2 create mode 100644 roles/traefik/vars/main.yml create mode 100644 roles/traefik/vars/main.yml-template create mode 100644 scripts/notify.sh.j2 create mode 100644 scripts/rclone.conf create mode 100644 tasks/base.yml create mode 100644 tasks/comprofix.com.yml create mode 100644 tasks/dozzle-agent.yml create mode 100644 tasks/dozzle.yml create mode 100644 tasks/gitea-runner-homelab.yml create mode 100644 tasks/gitea.yml create mode 100644 tasks/gotify.yml create mode 100644 tasks/homepage.yml create mode 100644 tasks/idrac.yml create mode 100644 tasks/invoiceninja.yml create mode 100644 tasks/iscsi.yml create mode 100644 tasks/jellyseerr.yml create mode 100644 tasks/lidarr.yml create mode 100644 tasks/mariadb.yml create mode 100644 tasks/mealie.yml create mode 100644 tasks/mediawiki.yml create mode 100644 tasks/omada.yml create mode 100644 tasks/osticket.yml create mode 100644 tasks/postgres.yml create mode 100644 tasks/prowlarr.yml create mode 100644 tasks/pykms.yml create mode 100644 tasks/radarr.yml create mode 100644 tasks/readarr.yml create mode 100644 tasks/sabnzbd.yml create mode 100644 tasks/sonarr.yml create mode 100644 tasks/speedtest.yml create mode 100644 tasks/traggo.yml create mode 100644 tasks/vaultwarden.yml create mode 100755 vault.sh diff --git a/.gitea/ISSUE_TEMPLATE/adding.yml b/.gitea/ISSUE_TEMPLATE/adding.yml new file mode 100644 index 0000000..c234d44 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/adding.yml @@ -0,0 +1,74 @@ +name: 'Add Application' +description: 'Track the process of adding a new application' +title: 'Add Application: [Application Name]' +labels: + - addition +assignees: '' + +body: + - type: markdown + attributes: + value: | + ## Application Details + + - type: input + id: application-name + attributes: + label: Application Name + description: Name of the application to be added + placeholder: Name of the application + + - type: textarea + id: application-description + attributes: + label: Application Description + description: Provide a brief description of the application and its purpose + placeholder: Description of the application + + - type: checkboxes + id: application-reason + attributes: + label: Reason for Addition + description: Please select one or more reasons for adding the application + options: + - label: New functionality + - label: Performance improvement + - label: Security enhancement + - label: Replacing another application + description: Provide the name of the application being replaced, if applicable + - label: Other (please specify) + description: Provide additional details + + - type: markdown + attributes: + value: | + ## Steps to Add + + - type: checkboxes + id: steps-to-add + attributes: + label: Steps to Add + description: Please check off each step as it is completed + options: + - label: Add Configuration Files + description: Create and add configuration files for the new application + - label: Update Wiki + description: Create or update the Wiki page for the new application and update any relevant architecture diagrams or flowcharts + - label: Update README(s) + description: Add the new application to the main table and any other relevant sections + - label: Add to CD Platform Logic + description: Add necessary logic to the CD platform for the new application + - label: Testing and Validation + description: Ensure the application is tested and validated in the environment + + - type: markdown + attributes: + value: | + ## Commit IDs for Completed Steps + + - type: textarea + id: commit-ids + attributes: + label: Commit IDs + description: Enter the commit IDs for the completed steps above + placeholder: Enter commit IDs separated by commas diff --git a/.gitea/ISSUE_TEMPLATE/feature-request.yml b/.gitea/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 0000000..52a17b9 --- /dev/null +++ b/.gitea/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,50 @@ +name: 'Feature Request' +description: 'Suggest a new feature for the project' +title: 'Feature Request: [Summary]' +labels: + - enhancement +assignees: '' + +body: + - type: markdown + attributes: + value: | + ## Feature Request + + **Please fill out this template with the requested information.** + + - type: input + id: summary + attributes: + label: Summary + description: A concise description of the feature you'd like to see added. + placeholder: Brief summary of the feature request + + - type: textarea + id: motivation + attributes: + label: Motivation + description: Explain why this feature would be beneficial to the project. What problem does it solve or what value does it bring? + placeholder: Describe the motivation behind the feature request + + - type: textarea + id: detailed-description + attributes: + label: Detailed Description + description: | + Provide a detailed explanation of the proposed feature. Include: + - How would this feature be used? + - What are the expected benefits of this feature? + - Are there any potential drawbacks or limitations to consider? + placeholder: Provide a detailed description of the feature + + - type: textarea + id: additional-context + attributes: + label: Additional Context + description: | + Include any relevant information such as: + - Links to external resources (e.g., documentation, articles) + - Screenshots or mockups to illustrate the feature + - Use cases and examples of how the feature would be used + placeholder: Add any other context or screenshots about the feature request here \ No newline at end of file diff --git a/.gitea/workflows/deploy-containers.yml b/.gitea/workflows/deploy-containers.yml new file mode 100644 index 0000000..255883c --- /dev/null +++ b/.gitea/workflows/deploy-containers.yml @@ -0,0 +1,30 @@ +name: Deploy + +on: + push: + branches: + - master + +jobs: + deploy: + name: Prepare Build + runs-on: homelab-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Deploy containers + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts + chmod 644 ~/.ssh/known_hosts + eval $(ssh-agent -s) + ssh-add <(echo "${{ secrets.SSH_PRIVATE_KEY }}") + echo "HOST *" > ~/.ssh/config + echo "StrictHostKeyChecking no" >> ~/.ssh/config + echo "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > ~/.vault_password.txt + echo "nameserver 10.10.10.1" > /etc/resolv.conf + ansible-galaxy install oefenweb.fail2ban + ./.gitea/workflows/deploy.sh "${{ github.event.before }}" "${{ github.sha }}" diff --git a/.gitea/workflows/deploy.sh b/.gitea/workflows/deploy.sh new file mode 100755 index 0000000..0293823 --- /dev/null +++ b/.gitea/workflows/deploy.sh @@ -0,0 +1,13 @@ +#!/bin/bash +changed_tasks=($(git diff --name-only $1 $2 | grep '\.yml$')) +if [ ! -z "$changed_tasks" ]; then + for task in "${changed_tasks[@]}"; do + tag=$(echo "$task" | awk -F/ '{print $2}') + if [[ "$tag" != "deploy-homelab.yml" && "$tag" != "main.yml" && "$tag" != "all.yml" && "$tag" != "all.example.yml" && "$tag" != "ISSUE_TEMPLATE" && "$tag" != "workflows" ]] ; then + tag=${tag%.*}_install + ansible-playbook main.yml --tags "$tag" --vault-password-file ~/.vault_password.txt + fi + done +else + echo "No changes detected in task files. Skipping Ansible playbook execution." +fi \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fcc6358 --- /dev/null +++ b/README.md @@ -0,0 +1,175 @@ +![Header Image](https://miro.medium.com/v2/resize:fit:4000/1*16DgdobhWUUXKzF4fwjOdw.png) + +
+ +# Homelab + +Homelab deployed as Infrastructure as Code (IaC) using ansible. +
+ + + +
+ + + +| Hypervisor | OS | Tools | Firewall | +|---|---|---|---| +| [![Proxmox](https://img.shields.io/badge/-Proxmox-%23c9d1d9?logo=Proxmox)](https://www.proxmox.com) | [![Debian](https://img.shields.io/badge/Debian-%23c9d1d9?&logo=Debian&logoColor=red)](https://www.debian.org/releases/stable/) | [![Gitea](https://img.shields.io/badge/gitea-%23c9d1d9?logo=gitea&logoColor=green)](https://about.gitea.com/) [![Docker](https://img.shields.io/badge/-Docker-%23c9d1d9?logo=docker)](https://www.docker.com/) | [![pfSense](https://img.shields.io/badge/-pfSense-%23c9d1d9?logo=pfsense&logoColor=blue)](https://www.pfsense.org/) + +
+ +This is a complete rewrite of previous IaC code to allow for better functionalilty and rebuild. Also using a VPS for containers that need to be always up incase lab server goes offline. + + \ No newline at end of file diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..f96f6fb --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,6 @@ +[defaults] +inventory=hosts +deprecation_warnings=False +host_key_checking=False +interpreter_python=auto_silent + diff --git a/build-debian-promox-template.yml b/build-debian-promox-template.yml new file mode 100644 index 0000000..83c4295 --- /dev/null +++ b/build-debian-promox-template.yml @@ -0,0 +1,78 @@ +--- +- hosts: proxmox + become: yes + + tasks: + + - name: Write notify script + ansible.builtin.template: + src: scripts/notify.sh.j2 + dest: /tmp/notify.sh + + - name: Delete existing template + community.general.proxmox_kvm: + api_host: "{{ api_host }}" + api_user: "{{ api_user }}" + api_password: "{{ api_password }}" + node: "{{ node_target }}" + name: "debian-12-generic-amd64" + state: absent + + - name: Download cloud-init image + register: image + ansible.builtin.get_url: + url: "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2" + dest: /tmp + mode: '0644' + force: true + + - name: Install Tools + ansible.builtin.apt: + name: + - libguestfs-tools + - python3 + - python3-pip + - python3-proxmoxer + update_cache: true + install_recommends: false + state: present + + - name: Install Tools to cloud-init image + ansible.builtin.shell: | + virt-copy-in -a {{ image.dest }} /tmp/notify.sh /usr/local/bin + virt-customize -a {{ image.dest }} --run-command 'chmod +x /usr/local/bin/notify.sh' + virt-customize -a {{ image.dest }} --run-command 'sed -i "s|primary.*|primary: https://deb.debian.org/debian|g" /etc/cloud/cloud.cfg' + virt-customize -a {{ image.dest }} --run-command 'apt update' + virt-customize -a {{ image.dest }} --install qemu-guest-agent + + - name: Create new VM template from cloud-init image + community.general.proxmox_kvm: + api_host: "{{ api_host }}" + api_user: "{{ api_user }}" + # api_password: "{{ api_password }}" + api_token_id: "{{ api_token_id }}" + api_token_secret: "{{ api_token_secret }}" + api_port: "8006" + node: "{{ node_target }}" + name: "debian-12-generic-amd64" + agent: "enabled=1" + bios: ovmf + boot: 'order=scsi0' + cores: 4 + sockets: 1 + machine: q35 + memory: 4096 + ostype: "l26" + vga: std + scsihw: 'virtio-scsi-single' + net: + net0: 'virtio,bridge=vmbr0,firewall=1,tag=10' + ipconfig: + ipconfig0: 'ip=dhcp' + template: true + timeout: 600 + vmid: 10000 + + - name: Import HDD to Template + command: + cmd: "qm set 10000 --scsi0 {{ storage_target }}:0,iothread=1,discard=on,import-from=/tmp/debian-12-generic-amd64.qcow2,format=raw" diff --git a/frigate.yml b/frigate.yml new file mode 100644 index 0000000..17b8b97 --- /dev/null +++ b/frigate.yml @@ -0,0 +1,10 @@ +--- +- hosts: frigate + become: yes + pre_tasks: + - name: Base Install + include_tasks: tasks/base.yml + roles: + - role: docker + tags: docker_install + tags: frigate_install \ No newline at end of file diff --git a/group_vars/all.yml b/group_vars/all.yml new file mode 100644 index 0000000..fd53115 --- /dev/null +++ b/group_vars/all.yml @@ -0,0 +1,124 @@ +$ANSIBLE_VAULT;1.1;AES256 +38386463636233373264323131333862626466386564393661613466323530633631613133656138 +3135346230633433346361376665316331666231386339610a393037323931653836626262626263 +32386638393261393037663262626266306565626363663263666231313939643964316264316233 +3531653138643236660a656165383736373438646235633566373839393038303263343265306231 +37393930643634656665336531616337353063343537396266646530613162356264343730366161 +65643264343462396634363739656264643330393832383233313031363937653565663831323134 +32356565646433386263643866633261383864626231316134376331646339396134616136623934 +66363739303661316338323237656463616331333233303331636662663439333533313063663738 +66666162343131313631373765303732323461643539356135386466613164393463623230633938 +62643134393033653634376333666230613636666239386439343562383034663561326438356434 +31303762643863353531363937343237663964363830316539613739396163393163326538303332 +62383436303537363765633465383661663433643466646131303464306130393237353665666466 +65613530383233353561656235303531343065613364363931633962373233666135646433396338 +38313738376431616161653961646265386166643965343364393263353837373536366461633766 +65306463626435613431363565303966396362393366373361653138646266346433356363333035 +64393664366232623231386237626131333165303132313935613564333038323662373238633364 +30383030323236313333616266643433616232383636633664363064383833633165656136306464 +34313461626531333530396536393937613363323061393436353161393034613762326264613331 +63626462643337353430623766333232393162346632343462303734623461623033616636313333 +66346135366530343134656361653035373832323835336637663535303337393662626134373762 +62656561343366313763366335646266323164366665633631376230386634336362316362336462 +65303536313234636661626437633265666562656330623766353731393062303236376530613263 +36383434623030363537356430373636623365333230656637373536323866343833353831653163 +30666530333935396261373630396331303736626433663739373437353036346561333238386665 +32383531633331376230366632336663376438353231366639643765383337646630306531313064 +66663566303362353264306337303638623335366339303365336234383464396264646563636536 +33383832353739393564613236353030396533666338363231623132303436663365373865326136 +63663631656665343632396465306234383234303732623166633031633239326131363737306361 +36323066623839643339313863363534313231386563393364313835633635636233663536326333 +35346461626266376637313334633039383662626161623462656535393136386363326663373463 +66353834613939643862386565366136356237313231656437363266303231376336353532333438 +63346165363031383136636238376635613939636165303366303266616165393863323430396362 +38303833616462643339316439366539373066643937313134663838363131383533356466656232 +61316264316564316330326265383766643037666138393565633133373437653934653032386136 +39643134636431613533633139396338623631623536333930646634366636656662383133383236 +31653266336462623565343266663134323939323637663630653164326531303934646131313932 +35643330353033613731366164323534386633623565633564376436343532396530636165616438 +31383130653230383730623939656437316161306235643132313633633162626561343339303761 +32343637366362346235383765366633333337366232386661363662643633613830366661393832 +38313565616433633039636665383539333633383734313661313766353062626430363034333862 +34336332306335646362333766346135383738333065633934396134373463333162666362653630 +30633365346165383361646633353231343532343532353536383464636566643665346236363632 +62333766343138393763333539633532623330623136613738626136633162366534613932643463 +62613131376263333063376638323737666564653664306632366331366332663566666133613534 +61393435333332333961376534363131633461373331323634333833306436663938386166393635 +38373136393737333736373062363837363533323031356665353766383164383036346530313831 +36393033323331353836623362386630643737343536376662643931393863653865613139353138 +38633064343837313564343834613132306239666630636336626234363964653939303366363566 +39666465396465356261346234346435356162366564643436313033316338376431303330313539 +61613538326336386230616339363462353138666362306565653766323639333638343863326636 +32363534333131356535643063316233376336636633643630363761396464646438613239386563 +37356333303133666439653632653533636336306266376535356330353337343332313637616336 +62396131633162356135356439363534353032373765373635366533393061646331386633633239 +37346566353736653830633238623530393537373164323861343961366263303764643937316234 +38326361343163313135396461643037323962386262636566313761353033323263666631393830 +62326362333264323666616638313135636233646466366433306533393031353831366266393130 +30653630626239343330633736303831353336356636643938306239363533393066353034316338 +37336332386565646364336331316632393864623066646231346135303163623833636632376338 +30363234313863396663633237613165373137343536623831366261393264326133356461643239 +35633937363761356564373230646365666666346630663935636262313932343534343963623635 +34326365646565616634386137323933653931373061303465663939373831366336653830653566 +36656631366434633065613430366236373165366365346664303266326136393438306563353265 +33323732653330373764363664363363363662626434626537386337383531303566663836356464 +34363635636161376530383930323361653063313338666162643234316363373835643633353738 +37663762326665336339373665626534303436626639313636636333383666613966343563613861 +36343961353339363137363539653435373132663263303533343935336435353161313036633364 +38326265313163623864666563373632303461393430613639616634613632303935393438333663 +61666166613738633163646130386364393137356436376666646162653937663137333764353032 +37353238613732623361613965316231623631623536623261643839323431396130363063316165 +38656635623762336465393764306261303666366538633565306637376664643963343239356466 +35656337643361326262643262326136306666303138663533373966363739663131653463363935 +33326438393464643436326263663066623233386132636136636636646133303565326231306237 +34383235356238326561396130306362303263376466393462663938643362353165386435666430 +62656234323537323534356561646662306630383330386631323334373934393864666664306566 +39303661656231373032643239303866633434626131366164316439656466613830626262663538 +36373437646464323265643365393165396230316636343466623962663038356163373433313335 +31663566626136313436643237316631636133353635613862333632613537313531623036623961 +66313131653731386333383962346634346138663666393138323661306239643736383533376432 +65653663303539326566646637333235653030356364623565633964303866313364663539303935 +34373536663935623638613930366533316334303566366265386266333466623331326635346330 +62323537666361626166323630303961363763386164613866613262336366633235323231626638 +30663038356535666638303134656634613134373837323736363430316137613335656531643062 +36356562383361393061663466323732383965313733633034346162653966313735393563656536 +32666361366430323239613437313833373330333336373636613463613566363337393161376535 +39336538323635656663613133356535373562383933616666666338373532346238353163616535 +33393461393365313764623332343332326535333533343934346138303132656234643731373238 +66633034643965633834333966323462323433613165303930343834663532626531343431396430 +33383732623165393032363437646430303062393032353632306439333261633963653638666232 +36613433303432623164646637316131333364323830323334633538333166306537343936393961 +61353831396338383436646636616363336564396336653634393666316566326165643562386534 +30383462323863336630643261613561663066343665313161643161333339623739323966383663 +65366562643363653534666666666234323964613732656334353534613966386233643335313736 +32303632336635656239326562386234383136346163396261653363316136343034386262333838 +62663966643530393964306437313534336666363765333431303239666164616665633332306466 +35356432393430663638376334663235663337393637343437376261653438663365653730343366 +38636538613731383833336231336432353561366265323933313239613836656437653935373663 +39303535613365343834373934343066383233326565623438373161626433323264353664316464 +61353265333636653039643934386361643931383033373636303138303635303361383538353965 +61613639616136376633303634643135613134373763323635386230393339633133373332636161 +66616338343737613333656234363663636132326665333734303036643966383239303563636563 +64366437656265656466376465613233653838343038663862643330653430613237656435383835 +37663866626663303032656163663635373037323839623439323264303333386338653930343666 +61306630653461346632313265313964393932376539663233333336313232363838343839643239 +61383062306333376330393337356364343131383530653461383737366431646236366538376632 +61636638323166303666633766623836626431333636626462653633343538303135323532343636 +62646333623164343665363039373139643466363366653935643365386131333632653031306165 +62663864383739303161356134643664396363303964663161383033393333303733626366316662 +39646466313534386637636562313163393865366631613838353637653533313232313666313838 +31613166653262386633393663366639336232383166633033303435643262656131343338643832 +66626533306430623733386233633561306536386262623030306630363362646338616634396339 +62363736646234383935383930343464643864393162656663386437323636613033643439613333 +34633266363264636466353135356537653931383131653863386137643032646664643133656536 +34343864643366376663616437373363636233343439353264656638326338333262386534346136 +35656130643533343736623564386537363737343761303739646361633165643963393166336265 +38336530333933653462393263316164383162373065663937363736623430373863303330323261 +34656534363235353032366237646336373039613836626130633738313664663162393031386561 +39373564343533373263306261653537663439326462393735343964323565343031646163333939 +62623834623939313438353939653138626165353434386638613439363739363465613037616636 +37333732333634333934633037613038323934636434303731363535663732663361613261663734 +35373061356665663936333438336132643930323463373635633137663132333362306136303830 +34613962356439303664323734643265313131643135366531643235633037646337313537323033 +31313837376134363664343766316436346162363264383165383561656362316633383136316533 +653961363033343965336230373962656537 diff --git a/group_vars/all.yml-templace b/group_vars/all.yml-templace new file mode 100644 index 0000000..cde266c --- /dev/null +++ b/group_vars/all.yml-templace @@ -0,0 +1,82 @@ +--- +ansible_user: administrator +data_folder: "/data" +install_packages: # Add addition packages here + - rsyslog + - htop + - vim-nox + - git + - zsh + - curl + - wget + - apt-transport-https + - ca-certificates + - gnupg2 + - python3 + - python3-pip + - nfs-common + - cron + - jq + - sudo + - logwatch + - sendemail + - libio-socket-ssl-perl + - libnet-ssleay-perl + - iptables-persistent + - rclone + - parted + - open-iscsi + + + +MYSQL_ROOT_PASSWORD: MYSQLPASSWORD +MYSQL_HOST: MYSQLHOSTNAME + +MAIL_HOST: SMTPHOST +MAIL_PORT: 25 +MAIL_FROM: emailfrom@email.com +MAIL_FROM_NAME: EMAIL NAME +MAIL_ADMIN: emailadmin@email.com + +#Postgres +POSTGRES_PASSWORD: POSTGRESADMIN + +# Proxmox API variables +api_host: "{{ ansible_host }}" +api_user: root@pam +api_password: APIPASSWORD +api_token_id: APIID +api_token_secret: xxxxxxx + +# Proxmox node target +node_target: pve + +# VM storage target +storage_target: local-zfs + +#Gitea +gitea_db_root_password: "GITEA_ROOT_PASSWORD" +gitea_db_user: "GITEA_DBUSER +gitea_db_password: "GITEA_DBPASS" + +OG_GITEA_KEY: xxxxxxx +OG_GITEA_SECRET: xxxxxxx + +# Invoice Ninja Variables +IN_APP_KEY: base64:xxxxxx +IN_APP_URL: https://invoice.ninja.com +IN_DB_DATABASE: invoiceninja +IN_DB_USERNAME: invoiceninja +IN_DB_PASSWORD: invoiceninja + +#Speedtest-Tracker +ST_DATABASE: speedtest_tracker +ST_DB_USERNAME: speedtest_dbuser +ST_DB_PASSWORD: speedtest_dbpass + +GITEA_RUNNER_TOKEN: gitea_runner_token + +VAULTWARDEN_BACKUP_ZIP_PASSWORD: vaultwarden_password + +TEAMS: webhook_teams_url + diff --git a/hosts b/hosts new file mode 100644 index 0000000..5b7b82d --- /dev/null +++ b/hosts @@ -0,0 +1,18 @@ +[proxmox] +pve2.comprofix.xyz ansible_user=root + +[cloud] +vps02.comprofix.com + +[docker] +docker.comprofix.xyz + +[omada] +omada-lxc.comprofix.xyz ansible_user=root + +[vps] +vps01.comprofix.com + +[jellyfin] +jellyfin.comprofix.xyz + diff --git a/main.yml b/main.yml new file mode 100644 index 0000000..cce5fd7 --- /dev/null +++ b/main.yml @@ -0,0 +1,191 @@ +--- +- hosts: all + name: Configure all servers + tasks: + - name: Gather facts if run with tags + ansible.builtin.setup: + when: (ansible_run_tags | length) > 0 + tags: always + +- hosts: jellyfin + become: yes + tasks: + - include_tasks: tasks/base.yml + tags: base_install + +- hosts: cloud + become: yes + roles: + - role: oefenweb.fail2ban + vars: + fail2ban_services: + - name: sshd + port: 22 + maxretry: 3 + bantime: -1 + tags: fail2ban + + - role: docker + tags: docker_install + + - name: traefik + vars: + traefik_host: traefik01.comprofix.com + tags: traefik_install + + tasks: + - name: Deploy Vaultwarden + import_tasks: tasks/vaultwarden.yml + tags: vaultwarden_install + + - name: Deploy gitea + import_tasks: tasks/gitea.yml + tags: gitea_install + + - name: Gotify + import_tasks: tasks/gotify.yml + tags: gotify_install + tags: cloud_install + +- hosts: docker + become: yes + pre_tasks: + - name: Connect iscsi + import_tasks: tasks/iscsi.yml + tags: iscsi_connect + + roles: + - role: oefenweb.fail2ban + vars: + fail2ban_services: + - name: sshd + port: 22 + maxretry: 3 + bantime: -1 + tags: fail2ban + + - role: docker + tags: docker_install + - role: nfs + mounts: + - name: Data share + path: /mnt/nfs/data + src: truenas.comprofix.xyz:/mnt/datapool/data + tags: nfs_install + - role: traefik + vars: + traefik_host: traefik02.comprofix.xyz + tags: traefik_install + tasks: + - name: Deploy comprofix.com website + import_tasks: tasks/comprofix.com.yml + tags: comprofix_install + + - name: Deploy iDrac Fan Controller + import_tasks: tasks/idrac.yml + tags: idrac_install + + - name: Deploy MariaDB + import_tasks: tasks/mariadb.yml + tags: mariadb_install + + - name: Deploy InvoiceNinja + import_tasks: tasks/invoiceninja.yml + tags: invoiceninja_install + + - name: Deploy Homepage + import_tasks: tasks/homepage.yml + tags: homepage_install + + # - name: Deploy osTicket + # import_tasks: tasks/osticket.yml + # tags: osticket_install + + - name: Deploy speedtest-tracker + import_tasks: tasks/speedtest.yml + tags: speedtest_install + + - name: Deploy dozzle + import_tasks: tasks/dozzle.yml + tags: dozzle_install + + - name: Deploy jellyseerr + import_tasks: tasks/jellyseerr.yml + tags: jellyseerr_install + + - name: Deploy lidarr + import_tasks: tasks/lidarr.yml + tags: lidarr_install + + - name: Deploy prowlarr + import_tasks: tasks/prowlarr.yml + tags: prowlarr_install + + - name: Deploy radarr + import_tasks: tasks/radarr.yml + tags: radarr_install + + # - name: Deploy readarr + # import_tasks: tasks/readarr.yml + # tags: readarr_install + + - name: Deploy sonarr + import_tasks: tasks/sonarr.yml + tags: sonarr_install + + - name: Deploy sabnzbd + import_tasks: tasks/sabnzbd.yml + tags: sabnzbd_install + + - name: Deploy mealie + import_tasks: tasks/mealie.yml + tags: mealie_install + + - name: Deploy pyKMS + import_tasks: tasks/pykms.yml + tags: pykms_install + + - name: Deploy mediawiki + import_tasks: tasks/mediawiki.yml + tags: mediawiki_install + + - name: Deploy traggo + import_tasks: tasks/traggo.yml + tags: traggo_install + + - name: Deploy gitea-runner-homelab + import_tasks: tasks/gitea-runner-homelab.yml + tags: gitea-runner-homelab_install + + tags: dockerserver_install + +- hosts: omada + become: yes + pre_tasks: + - name: Update packages + import_tasks: tasks/base.yml + + - name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "/data" + roles: + - role: docker + tags: docker_install + - role: nfs + mounts: + - name: Data share + path: /data + src: truenas.comprofix.xyz:/mnt/datapool/docker + tags: nfs_install + tasks: + - name: Deploy Dozzle Agent + import_tasks: tasks/dozzle-agent.yml + tags: dozzle-agent_install + + - name: Deploy Omada + import_tasks: tasks/omada.yml + tags: omada_install + tags: omada_lxc_install diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..bff1dcb --- /dev/null +++ b/renovate.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "local>RenovateBot/renovate-config", + ":semanticCommitTypeAll(chore)" + ], + "ignoreDeps": ["postgres"], + "automerge": true, + "automergeType": "branch", + "automergeStrategy": "rebase", + "commitBodyTable": true, + "ignoreTests": true, + "major": { + "automerge": false, + "commitMessagePrefix": "chore(deps-major): ", + "labels": ["dependencies", "breaking"] + } +} diff --git a/roles/docker/defaults/main.yml b/roles/docker/defaults/main.yml new file mode 100644 index 0000000..f0327f6 --- /dev/null +++ b/roles/docker/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for docker diff --git a/roles/docker/meta/main.yml b/roles/docker/meta/main.yml new file mode 100644 index 0000000..37aea76 --- /dev/null +++ b/roles/docker/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: Matthew McKinnon + description: Mounting NFS filesystem + company: support@comprofix.com + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml new file mode 100644 index 0000000..4b1a43a --- /dev/null +++ b/roles/docker/tasks/main.yml @@ -0,0 +1,49 @@ +--- +- name: Add Docker apt key. + ansible.builtin.get_url: + url: "{{ docker_apt_gpg_key }}" + dest: /etc/apt/trusted.gpg.d/docker.asc + mode: "0644" + force: false + checksum: "{{ docker_apt_gpg_key_checksum | default(omit) }}" + ignore_errors: true + +- name: Add Docker repository. + apt_repository: + repo: "{{ docker_apt_repository }}" + state: present + filename: "{{ docker_apt_filename }}" + update_cache: true + +- name: Install Docker packages. + package: + name: "{{ docker_packages }}" + state: "present" + +- name: Install Docker Module for Python + pip: + name: + - PyYAML==5.3.1 + - docker + - docker-compose + - pymysql + - passlib + state: "present" + +- name: Ensure docker users are added to the docker group. + user: + name: "{{ item }}" + groups: docker + append: true + with_items: "{{ docker_users }}" + +- name: Reset ssh connection to apply user changes. + meta: reset_connection + +- name: Setup cron job for backup + cron: + name: Docker Prune + weekday: 0 + minute: 0 + hour: 5 + job: "docker system prune -af && docker image prune -af && docker system prune -af --volumes" diff --git a/roles/docker/vars/main.yml b/roles/docker/vars/main.yml new file mode 100644 index 0000000..6e2c3a0 --- /dev/null +++ b/roles/docker/vars/main.yml @@ -0,0 +1,51 @@ +$ANSIBLE_VAULT;1.1;AES256 +32396236613762346266373632613335306233666563346466653731653034613637656335636463 +3864336133316534333262373835643732303963353538320a343235363461613837383962303762 +62373739653137326664306563646632663661323339626636333461303132366133393266313833 +6137313537666138320a376334396531643233626265643538613133313866623236383338353035 +62623166316366393837313166646539376362383363353862303439303230376163366335353237 +66626130373762333536396265663262376335323162633961656139313435333765363163633161 +65393532663339363738623232316135326338656330303764633530663661626163343533643430 +63646337363636386337373435373939363434646161616638326665316636383362346232303763 +39656636643261383137306339633433613534313362636537393433656230613333333463396437 +32623630636464313665656562393766376330633038366534623634656535303237666332363638 +36373566303432653664383230626436663362323336336233396363353430353535336464376137 +33393762363330633963656161383535306365383062616466626266373637396338643930333931 +66373739303232393233303131663031333639346236633030346337313938383739386561386263 +36643831323930666665376237656163393532333438346332653562306532636530386365636331 +38643637613261373030323963656266613661656663643330383333336336383433393633383335 +65326130646536323861346437336362333630613034366639656536353430326366316530396436 +34636235336433666261386163316330363337393963643761646261633932666134316331386463 +63643463343162313162323537623764303564343438636133643162646530643435306262653838 +30376539303130303536316136383761333836646231316563633564643635376230313333653739 +38663032343736626461303835656662323064666139323935323534346362383636636237333937 +34616663666364323734643530343936383030326539623065356561633563653764386134633562 +37616463633931336233623335336331313463656132653331303530616332306332613936623130 +63616264333531303762663665323636663466313933393064623534653561343561633632636565 +39633435313963393034366336316665323339333962343666666533646632343666393332323635 +65653062643332663362343666643433336562353639656366623961306132313734613838336237 +36653962353839636662363335373238393433613037623364356637336562303765313466313166 +34326365393433646166653461333138386166663537343566633565316163323866333932366432 +34666532346164316232663964666132653232393264633066333734333238636135376263643937 +66353665353564353938343934363337396165616462336439363338343065306533653334636566 +35356231346431646237636662633030313135633663336163383965656136393238636334396137 +65613833666662353339616434623735386638656331643831383134626163386636313633323333 +34383862373634373732613333656437323436383962306163633833343430303336383433366336 +63313138383237373330623536383438306330373164336637646165313562343935656566653531 +30356365333863383165633634343230653735343164393030313339653563376435313832396266 +65623237393066666163363530356163313861323366373233383531386533623965306237623137 +33363239396634306466663535323736373333643266336164336230303836643939343335626339 +35373166616136633666323034313364613334303462616564383861343738653964663332616536 +32353135633331336239353834666237313939386334383261663532333139636363353436363864 +33396336623566346532613738353332643965623335653162323534613330663964353833333937 +30373761393834323964633039393339376538353261396331316336323333383064356363633264 +62613432313436353163383837363935373164366236343936313366623936336439613364336639 +63336536333732326236323761323033613965333763366237316431303363346263373131663338 +65376535386239353362326630396232623533626266376233326330316466383564313935663134 +65363839323134663537356663346437616662366463393036353736353664356538656163353562 +65323162663934653462353136353065333666353564313066613466663734623066623439613964 +36353035653163306661393335636430623233633962303033656539363265663135666663643164 +37613334653964366433646366613861336335373137393065373739363863626334316631323332 +66623465373730373231316265653330383061326231373931636132663233643735343564313636 +36313330336461616134663336306566646639383435396236383162366266366662383635333832 +3266363963363362343563653131373339666163663536653032 diff --git a/roles/docker/vars/main.yml-template b/roles/docker/vars/main.yml-template new file mode 100644 index 0000000..47cf56f --- /dev/null +++ b/roles/docker/vars/main.yml-template @@ -0,0 +1,21 @@ +--- +# vars file for docker +docker_edition: 'ce' +docker_packages: + - "docker-{{ docker_edition }}" + - "docker-{{ docker_edition }}-cli" + - "docker-{{ docker_edition }}-rootless-extras" + - "containerd.io" + - "docker" + - "docker-compose-plugin" +# Docker repo URL. +docker_url: https://download.docker.com/linux +docker_apt_repository: "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/docker.asc] {{docker_url}}/{{ ansible_distribution | lower}} {{ansible_distribution_release}} stable" +docker_apt_ignore_key_error: true +docker_apt_gpg_key: "{{ docker_url }}/{{ ansible_distribution | lower }}/gpg" +docker_apt_gpg_key_checksum: "sha256:1500c1f56fa9e26b9b8f42452a553675796ade0807cdce11975eb98170b3a570" +docker_apt_filename: "docker" +# A list of users who will be added to the docker group. +docker_users: [administrator] # CHANGE_ME!!! - Add addition users. +# Docker daemon options as a dict +docker_daemon_options: {} \ No newline at end of file diff --git a/roles/nfs/defaults/main.yml b/roles/nfs/defaults/main.yml new file mode 100644 index 0000000..abd341c --- /dev/null +++ b/roles/nfs/defaults/main.yml @@ -0,0 +1,8 @@ +--- +# defaults file for roles/nfs-mount + +# List of NFS shares +nfs_share_mounts: [] + +# Default NFS4 mount options +nfs_mount_opts: "rw,sync,hard" \ No newline at end of file diff --git a/roles/nfs/meta/main.yml b/roles/nfs/meta/main.yml new file mode 100644 index 0000000..37aea76 --- /dev/null +++ b/roles/nfs/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: Matthew McKinnon + description: Mounting NFS filesystem + company: support@comprofix.com + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/nfs/tasks/main.yml b/roles/nfs/tasks/main.yml new file mode 100644 index 0000000..27a5cf2 --- /dev/null +++ b/roles/nfs/tasks/main.yml @@ -0,0 +1,20 @@ +--- + +- name: Install NFS mount utility + ansible.builtin.apt: + update_cache: true + pkg: nfs-common + state: present + when: ansible_os_family == "Debian" + +- name: Mount an NFS volume + ansible.posix.mount: + src: "{{ item.src }}" + path: "{{ item.path }}" + opts: "{{ item.opts | default(nfs_mount_opts) }}" + state: "{{ item.state | default( 'mounted' ) }}" + fstype: nfs + with_items: "{{ mounts }}" + + + diff --git a/roles/traefik/defaults/main.yml b/roles/traefik/defaults/main.yml new file mode 100644 index 0000000..205c4a1 --- /dev/null +++ b/roles/traefik/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for common diff --git a/roles/traefik/meta/main.yml b/roles/traefik/meta/main.yml new file mode 100644 index 0000000..17d2a6b --- /dev/null +++ b/roles/traefik/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: Matthew McKinnon + description: Traefik Proxy + company: support@comprofix.com + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.1 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/traefik/tasks/main.yml b/roles/traefik/tasks/main.yml new file mode 100644 index 0000000..07a96ae --- /dev/null +++ b/roles/traefik/tasks/main.yml @@ -0,0 +1,95 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/traefik" + - "{{ data_folder }}/traefik/data" + - "{{ data_folder }}/traefik/data/log" + + +- name: Create a network + docker_network: + name: proxy + register: network + +- name: Copy Traefik config + template: + src: templates/traefik.yml.j2 + dest: "{{ data_folder }}/traefik/data/traefik.yml" + mode: "0600" + +- name: Copy Traefik config + template: + src: templates/config.yml.j2 + dest: "{{ data_folder }}/traefik/data/config.yml" + mode: "0600" + when: traefik_host == "traefik02.comprofix.xyz" + +- name: Check if {{ data_folder }}/traefik/data/acme.json exists + ansible.builtin.stat: + path: "{{ data_folder }}/traefik/data/acme.json" + register: file_status + +- name: Creates {{ data_folder }}/traefik/data/acme.json if it doesn't exists + ansible.builtin.file: + path: "{{ data_folder }}/traefik/data/acme.json" + state: touch + owner: root + group: root + mode: "0600" + when: not file_status.stat.exists + +- name: Check if traefik.json.log exists + ansible.builtin.stat: + path: "{{ data_folder }}/traefik/data/log/traefik.json.log" + register: file_status + +- name: Creates traefik.json.log if it doesn't exists + ansible.builtin.file: + path: "{{ data_folder }}/traefik/data/log/traefik.json.log" + state: touch + owner: root + group: root + mode: "0600" + when: not file_status.stat.exists + +- name: Create traefik Container + docker_container: + name: traefik + image: traefik:v3.5 + restart_policy: unless-stopped + networks: + - name: "proxy" + ports: + - 80:80 + - 443:443 + env: + CF_API_EMAIL: "{{ CF_API_EMAIL }}" + CF_DNS_API_TOKEN: "{{CF_DNS_API_TOKEN}}" + volumes: + - /etc/localtime:/etc/localtime:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + - "{{ data_folder }}/traefik/data/traefik.yml:/traefik.yml:ro" + - "{{ data_folder }}/traefik/data/acme.json:/acme.json" + - "{{ data_folder }}/traefik/data/log:/var/log/traefik" + - "{{ data_folder }}/traefik/data/config.yml:/config.yml:ro" + labels: + traefik.enable: "true" + traefik.http.routers.traefik.entrypoints: "http" + traefik.http.routers.traefik.rule: "Host(`{{traefik_host}}`)" + traefik.http.middlewares.traefik-auth.basicauth.users: "{{ traefik_api_user }}:{{ traefik_api_password | password_hash('blowfish','1234567890123456789012') }}" + traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme: "https" + traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto: "https" + traefik.http.routers.traefik.middlewares: "traefik-https-redirect" + traefik.http.routers.traefik-secure.entrypoints: "https" + traefik.http.routers.traefik-secure.rule: "Host(`{{traefik_host}}`)" + traefik.http.routers.traefik-secure.middlewares: "traefik-auth" + traefik.http.routers.traefik-secure.tls: "true" + traefik.http.routers.traefik-secure.tls.certresolver: "cloudflare" + traefik.http.routers.traefik-secure.tls.domains[0].main: "comprofix.com" + traefik.http.routers.traefik-secure.tls.domains[0].sans: "*.comprofix.com" + traefik.http.routers.traefik-secure.tls.domains[1].main: "comprofix.xyz" + traefik.http.routers.traefik-secure.tls.domains[1].sans: "*.comprofix.xyz" + traefik.http.routers.traefik-secure.service: "api@internal" diff --git a/roles/traefik/templates/config.yml.j2 b/roles/traefik/templates/config.yml.j2 new file mode 100644 index 0000000..c9f0a6a --- /dev/null +++ b/roles/traefik/templates/config.yml.j2 @@ -0,0 +1,51 @@ +--- +http: + routers: + oc-router: + entryPoints: + - "https" + service: oc-service + rule: "Host(`omada.comprofix.xyz`)" # change it to actual address + tls: {} + middlewares: + - default-headers + - https-redirect + + services: + oc-service: + loadBalancer: + servers: + - url: https://omada-lxc.comprofix.xyz:8043 # change it to actual ip of the controller + + middlewares: + https-redirect: + redirectScheme: + scheme: https + permanent: true + + default-headers: + headers: + frameDeny: true + sslRedirect: true + browserXssFilter: true + contentTypeNosniff: true + forceSTSHeader: true + stsIncludeSubdomains: true + stsPreload: true + stsSeconds: 15552000 + customFrameOptionsValue: SAMEORIGIN + customRequestHeaders: + X-Forwarded-Proto: https + + default-whitelist: + IPAllowList: + sourceRange: + - "10.0.0.0/8" + - "192.168.0.0/16" + - "172.16.0.0/12" + - "100.64.0.0/10" + + secured: + chain: + middlewares: + - default-headers \ No newline at end of file diff --git a/roles/traefik/templates/traefik.yml.j2 b/roles/traefik/templates/traefik.yml.j2 new file mode 100644 index 0000000..aefe2b0 --- /dev/null +++ b/roles/traefik/templates/traefik.yml.j2 @@ -0,0 +1,42 @@ +api: + dashboard: true + debug: true + +entryPoints: + http: + address: ":80" + http: + redirections: + entryPoint: + to: https + scheme: https + https: + address: ":443" + +serversTransport: + insecureSkipVerify: true + +log: + level: DEBUG + filePath: /var/log/traefik/traefik.json.log + format: json + +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + file: + filename: /config.yml + +certificatesResolvers: + cloudflare: + acme: + email: {{ CF_API_EMAIL }} + storage: acme.json + dnsChallenge: + provider: cloudflare + #disablePropagationCheck: true # uncomment this if you have issues pulling certificates through cloudflare, By setting this flag to true disables the need to wait for the propagation of the TXT record to all authoritative name servers. + resolvers: + - "1.1.1.1:53" + - "1.0.0.1:53" + \ No newline at end of file diff --git a/roles/traefik/vars/main.yml b/roles/traefik/vars/main.yml new file mode 100644 index 0000000..7fb25bd --- /dev/null +++ b/roles/traefik/vars/main.yml @@ -0,0 +1,14 @@ +$ANSIBLE_VAULT;1.1;AES256 +61386364396339353533653064303734346336653531366139333738353461613037396365663265 +3731366362343630646162353636316565356563323135350a636335653931376137666139653739 +36306631376639336561643064386430633636343362646233623263356635636134303931356364 +6466383864366236320a376134623032383566643166626231323432373562373864333864653032 +63316630303362616337383833623733316131323764626532366338333566643834326236383232 +31646330363965386233383739336238336538666165383166393834643134663937393535333361 +34373236386339366436643733393030313331303537636233383864623435386166366537386633 +37653030313066393136616661356564373932643033663735656238313132396664623438343833 +65356539386435656433393933653939313635376639366163353336373661396230336533626238 +39643438313763343635393165376263666633363963623962643263323531616466656532646432 +62383430346666343465613436346637333336663562316165303864376464363566343165633665 +66353134313866393439323564353834346436326132643439383134623864333765616162353436 +6338 diff --git a/roles/traefik/vars/main.yml-template b/roles/traefik/vars/main.yml-template new file mode 100644 index 0000000..e20aa65 --- /dev/null +++ b/roles/traefik/vars/main.yml-template @@ -0,0 +1,5 @@ +--- +CF_API_EMAIL: CF_EMAIL +CF_DNS_API_TOKEN: "CF_API_TOKEN" +traefik_api_user: "admin" +traefik_api_password: "password" diff --git a/scripts/notify.sh.j2 b/scripts/notify.sh.j2 new file mode 100644 index 0000000..5ea10f7 --- /dev/null +++ b/scripts/notify.sh.j2 @@ -0,0 +1,2 @@ +#!/bin/bash +curl -H "Content-Type: application/json" -d '{"text": "Cloud-init provisioning has been completed on '"$(hostname)"'!"}' "{{ TEAMS }}" diff --git a/scripts/rclone.conf b/scripts/rclone.conf new file mode 100644 index 0000000..29ea247 --- /dev/null +++ b/scripts/rclone.conf @@ -0,0 +1,196 @@ +$ANSIBLE_VAULT;1.1;AES256 +63623637376239613064343634336463616165333831353331633738356662303534303133363338 +6334613838656263393764666534333434646232616662300a306638646461363133613365323635 +36383130373964333937643532356538303936666434653566616232363934336531353732653766 +6166333932323764350a643331313162376239643364633337376366363663306539363962613431 +64336561626166613061353962323461646664343637386664363530626666333930353365383334 +36313939626436663436623235656435666136653834336131303434663739626135643430613836 +63386138363963646433643966613331633563633834366364353337323762663232663865363666 +32336432323962366237323833656535386338646265336562396437663539346430636635623037 +38613330666362396562346137316132363764376265636337646430303437663233663464353465 +34663530323561626237333030376466636436396331643136343235316161343934646366353335 +63333762343033353066646236633437396365363464366231333462653239666237343564313934 +38373162616635633730316334613239383938626364633732353031616261363066653266346339 +39383537396635626639636433396263613231303030306136653262326538636232663131633531 +36336432666461356537353438386464396661613664303331313466663836353939383630396663 +63316363623235333934616635303461376138646530393936353934316431386234383364353166 +38346162633133623066343532316331313661336365323664353066663864353263653532623238 +66326535306537363831613538363761623366626436386261343365643239323863303263363334 +63626164656239643038663765613339633064323137303834333035343935383737646430316631 +35386534343563393636326164653062343139353265663032393830333663323831616562393665 +61313665633731313737626362353032316432656665623832333461353464313735623738386564 +38343464333264626161363839333534353131366130366361656363383465656233626334323830 +63306431353365356438393037666132366637383530653636363065323161623831346434343964 +34303730646531386265326430313733333233636337386639613466626335326465396536653337 +32613035646639666635366662653938326632373264343731396633383134636534343064646335 +39326263393131323665306636633435356234393864393835323662643636346262353961393162 +37663962613430626135653666306133613166393736633530313139613161333438383662353136 +32303033636634306562633739393831336333383931376536326137353935383537323464613362 +61326338643435633530333163613235386434343637346636366262336539333762643232643362 +64643032336264613664643433356238323836393236306136633038323436656335313733356166 +37393965643638626236626566363463633837343561353433373036636430643436613862346462 +38386432316631623432386661353765343338323164303535613864643264343363303365316465 +31626334646562323139623630363439613436373537626362643530613036306435383039363836 +30353932306332613034666439356232366430626230336566666162393437323864656663346639 +31633331386432323830343062383237356463363637336436306432396539306166613138333162 +61346634373336383732636638376330383131333961656534636663626335366264393733373234 +32623430336233653236633536626563356239636161373733633337643239613938336566336463 +34343236323664363561306337646133616431303764346437313938613430386131323335346331 +62383839633162366366613236303639643163303134383662313730666365376338376436656462 +36643161363738303531353364393764633139336239336632346164373766666336353339633737 +33393364306466656164616531663662613632323865623966393564613737643765343530346131 +63653233313335333335636161326265323263306636323761396131666339323534343133333966 +63343761343135616363363638366430313430666539303135623065313131666533386364623861 +36356233343566303161616337343536663236643634626139643563663231353131316561633232 +62666238653130633536626432313935353438613666353735613262336134346630343839306166 +65653732613666656636343737336331666434363065343930656463613837323765303737643764 +64616230373964363565306136623135663730323164623439393437366233643038303363663731 +63333666663831653763613632666437393438386534363533356138383231303439306235636537 +37636561613463333930323565303935313839653364653533636562653364666331326663333362 +33393839376262346431326236633839323234363861663963616531366538333338356339323330 +32643633656339333635363964313564343432383364323833646632343133623063383339626131 +38633638656232306161383961383665316638666166663038353266303233396234303263333162 +37306338363434613738643361663861613963643537353831316639323831346231633736356662 +66623637393165623566636437636438626634323862316662386465653437666336376632373735 +30343634393133653536616366383762323933316531343864363439616139663539663736336631 +66376430383436313838656337653465353736396430643334356339343533373634313136336337 +37633938353336336231383531376333653838613233363265646337353936363135313030303164 +31376632663165383863373332313561633836363464626633626661363936643432333365666131 +31643033636434356335363439633263343831326434316435616530666563613638326231323639 +37333466613934636332303738313362623364353133383037383366356333663935396566633431 +30373532326236626238396666643235303739383961663466643765373932653462356636653863 +65396130343236653334323031626536663965313065336338643166623434336130623434383665 +36613533316438366330393364373235326266616236363662396137666338613764633361656566 +38633235616139363765666632363934303234633062363130663462316462666439383736353232 +30383932396462306430663839326433303834373965663466643264663436633433656663613434 +66356563373662626634333265333033303930653737303434303363346331303333373933336435 +39633730613738373361383732373337666262363965656232323866316661313134396266666530 +31346162373463383666656535386430373465646266623431653161616533393133613131313533 +39383739613939393639616435653261323230663532363234613638303831313833326233366131 +39363165643531666337393661366563363131623235376665613633656162343131333637333663 +30376331666661316130616163393435343535356465326133326335373333643738306331323430 +33646462613065393334613833346565613964616665303933326139306230613465326433396439 +64643031626663383166326630303038656530633064376339373864303438366335393064316537 +63666532343164363166353036663336613433366636373437643830643732396462633635633764 +63343433313062353666383135633330353431376532393430316561633334653966306439613663 +31333934366161343361393438383164353965333565386262333737363535633663646665343032 +30396434636435353766343065613635613364396638343966393831646236313131633131363839 +38376539333131333763376161346634666137326464396432636562333538373962386239303761 +37633662376633303366613962333830393430623563303734363965663865303532376134383130 +34373335363664313536306465346534393834666264623261616465623962626262636332306636 +39616161656334303438666432386366646336633832626237333231333833613738346631643961 +39616137353738363461396635636336363335353838613938303465386131633038306130643533 +38633839653937353663636630653966653432656462346237313063613338353631666439613861 +30633030323165376435393965336139333133653939366533316636323032323764333834623964 +37343561396131343763313334626137386534353639383935353934333738653762383736313235 +33353233373133353631303238363934366339393838636266396432653361616162373963343065 +36373862616164383037343538663532313363613164383264643763376564396264323134346337 +37366261393436616566396431323265626334376662663964323963363262353332613662393737 +65313066386237353764363435613866613435323236643436333561346536333964666562643732 +39333739633232353630643333623238383461313530623435333263373562333564323464373430 +66653031333763633662646631633561656262353462386538343462633533353662633065346461 +37643437333265333337646631653765343036313638393638373035323534383036323039376338 +31613361306332376639636562343261343865653765633130313464666230306238353135623062 +31383638393064333763343139666663353531623533633033373039626564346436373439666331 +38663961663032653238633036383438393465353563363439353437366266353139383766656631 +65363032346433393166306131333131356339633561666134653432306661313663346566653238 +38316231363933613561313936613163356337646337653033396562613564666133613336623533 +63616235346262663666373239373832613835323238353039633737363030323166386230303734 +36313637383430656433613236363462343466666361303933646665346366663235306333656366 +34316663343962363561636166313265396363636233303830646633626663353933663266366363 +30393131313361353637663864636466323436663330343534353535643430303162633730383139 +37343633323965333463613434326232346639383035326234383234623238333635633036353462 +38303765643539336262656338633033366534373961373835643835633461646165656663613936 +32373532663861646537323638613832333631323239343865396434636132656332366335323337 +31663962366162363433353832386164333337386631653538656639383936383337623764636563 +30383738346236623565333466323566306138373565376334396464343265383034326436323836 +39323237396339653261626638373538383464313536343365333934306262633238383939626265 +66626661336462366236346632316662386336353436623562356639376230386530353438616430 +63316361626265356436343031383365323839626538393735393030666338343132663565376231 +39623634623833333432383739346339306434383764633635613461383262316135663461393737 +38346261323831643862383139333662666339663039386534386365656632366562633139613366 +33326230353161313064633539333131646436376139623966326236343937616630626335656663 +66303537633965376366303463333765613131663636373137613361363066326230643837636236 +37316435393538353166313933313665363936303066363933336436386139303465613665386165 +39366637313436366432623863306136363633303233313165646431656136613835623236623361 +32333131666630336330393737396135666163346131326232306362316166343633326664623030 +62313435623162356365623664643962343334313836333537663031343736636164383836343731 +62316636643361666136363364643038353330373334353663646139623362636163366666343434 +66383366643261333539333862336466376639303139666134393834336639386637376461653331 +35343932343835323035623034323633383663616530386139616566666635343236363739613237 +38653062383837653630323563343230303862623064306361633532356532343866373662343138 +33636365613331396433663364616331313663333132373934663130336335613639313762373564 +63363131346365613333633736323432386339373965623964626336626637316137346535326232 +36363431313166626164363663303932366134313933303135613231366330663330623831633539 +39623034343134303135643538396464316163393264353533623365613130393662626530636261 +35656663373030663331316133646561363565356438666533316563393433623661616630336465 +61383464366165343963623734346563616539356635356161376165356235306634636138633236 +66643535373931363732653764383939663762373063663839363166333761353633316232393338 +33343135623365393230303266633031343065346334363534383135343865346130653236333432 +64383466323365313731326563386131616338663061316330323964643166636464626537643736 +35656561353961613931613036653065363861353836386231646136643639373738643539353330 +32373737323332636563356131346233303037336130336137383264343438373264363161643037 +30353765393661343333366432353964383636373739346439333532336364316135343233336362 +36383637313733653263386330663363376135633437356566343035356239306666613035666662 +64613139303566363864303036613662636266333338386430366639356338313236633531623865 +63636233666338373630333733396365643337373662656131313830616435333562643139313333 +31316439663633363238316231633961613137643337306135326437643534376166666364333961 +38353562663062373461393736623634616663373365643630366462656639633637363436643163 +64306631653835616664303031383365643632316566383832323030643831303563336163636264 +30653237376534323339613030366439373930316466326261356136383131323335306334613365 +66623339643234656337643837623137326537306566383537366430333139313761663361393134 +61313663313139356537396439316337386132343930626161366464373162306162343863313261 +32656630636461633436306162396534313131626361363266393437353535306162326434653733 +35623561616132343338363534383335393939333065633462643561366333333034636363386533 +39333936663939383031356534363636383332613162323133396166303665653935376630636236 +31633361363236353663303338363033633133613334616264663431633335353936373963383838 +32343965396438663739646166366262323133333664386563643637373761323930383633333039 +64616635633937346165613962643965633033663134306261383737313466313065323666366138 +32633731363662306161353636333131623662336434366432303232306164323866646639616534 +31613061656137643137343261366462386533636166313965656531633237386537636166316138 +33353164313366343132636263626134656265343733646465383664653266623166616333666635 +38343165396233343633393963616138333138303938643732393530343032663765663036643762 +35373961303537613331323538323431343934386134663466336438323462343766653936353037 +62303537373038323836636464643361346337393330316532353737333732366261303761373531 +32323736336536356234643266383962623832656265303035376532663762306435323262363238 +31353661663563653932336532646632623832343832373263376434313066303039646234373237 +32626664343334613337386539343433336335303836616162616130613635306234343536396634 +61633836373937656435383639373130376637393239333137396535306263303030343565306463 +36653838323631356166363234353963353234363538353763326631366438343833626564616439 +32386534653133383634623330653936363364366633646566623038386562626365386163363630 +62366137633739373436633963623138366361343333666564663162346562383463666237353862 +37383033636563393039396535383535343364353338353731303539393638633462353230643034 +62656134346566366565646666666364646633626163623938653538353165396134636534353864 +31643633653463313461613935663964326135376166633166313762363831636532363333353437 +30333238323066316535303233646666613034333035383830383636633165333766663364383632 +62303030643239383931333533636534356635363538303236396666373731336335313762626337 +66393636353038333735326366613265653539613436303864353037316366613938356132356366 +36376666343532353161323965653336313161373764623339626330656139623764633836343639 +61366531353433646262303662303937306562353836626163353465393835633762353039326631 +62393063343865616165393039323533653165376132303564316330363434643139393337353133 +33353764333338656264643233316164613038346161383364383939626536353030346534356433 +65366535343565393366626531623665353130323563646166366433633030653035356334353966 +33346137633237363839383233313037663438663535623561653064356538623634336135313263 +33623739333339616261646664646634306534323534386665303166386431336164666663646236 +36396438653535393665666664653534353562303538656462346262316338343035303930633837 +38656335663365636237356632623631623161653839373933366539353733323464386330386134 +32343862623133633865313136663765366364646535326339633766333930323564386339383739 +66353037343837303164303430316235303131306166366136313433363137346563306133616461 +36653239323333356164636665353236353835636532623562326131323439323534316366616337 +35366335323164356439646336663938343366316538383838323764663163663935613364663631 +32653134613636393131623165353431376265313634396239306530393665303033393439636663 +37386363643737386661643638303038363662623266353963613130663735356631366530643663 +38613734373864353231363363396561303238353433373065356532303732353734613335616264 +66613565633535323564616261353363363839326331623365383262663263366664336361643561 +37393836323062313363386562633237353266336261383865333335356434336634303231306134 +33373165663638623464633464623531383664333237323164633231373163336633613232323937 +65616636393663623039623536663736636664333164363036356230653963623937356238613134 +39393536613834386438343163316161613739303730633765643938313662356333613031613365 +63613239303065633030666430396463383032333665383434646562306139356135616432666136 +38613561363662303735323031626433636632616635613664386230303537396132633337366364 +39303461373636623465383863396132393565636566313730393238306130333630343365656632 +66316532643762663563376331666437666538343363356562343634333861353530613733313035 +64366437393036363165316438383565633864383132343035333837663235356232646130363137 +33386436393533626133626636393665666233366663313163323563653131363637323739323664 +35653634616562376132363761373464323466393230616232343936666437316535303436323633 +333637333634306336326535393964323138 diff --git a/tasks/base.yml b/tasks/base.yml new file mode 100644 index 0000000..59d46d7 --- /dev/null +++ b/tasks/base.yml @@ -0,0 +1,224 @@ +--- +- name: Ensure facts are gathered + setup: + +- name: Ensure debian-archive-keyring is installed + apt: + name: debian-archive-keyring + state: present + update_cache: yes + become: yes + +- name: Update cache + apt: + force_apt_get: yes + update_cache: yes + when: ansible_distribution in ['Debian', 'Ubuntu'] + +- name: Update all packages to their latest version + apt: + name: "*" + force_apt_get: yes + state: latest + when: ansible_distribution in ['Debian', 'Ubuntu'] + register: upgrade_result + +- name: Upgrade all packages on servers + apt: + upgrade: dist + force_apt_get: yes + when: ansible_distribution in ['Debian', 'Ubuntu'] + register: dist_upgrade_result + +- name: Install required packages + package: + name: "{{ install_packages }}" + state: present + become: yes + register: install_result + when: ansible_distribution in ['Debian', 'Ubuntu'] + +- name: Reboot if required after updates + reboot: + reboot_timeout: 600 + test_command: whoami + when: + - upgrade_result.changed or dist_upgrade_result.changed or install_result.changed + - ansible_virtualization_type != "lxc" + become: yes + +- name: Gather facts after reboot + setup: + +# --- Upgrade Bookworm to Trixie --- +- name: Upgrade Bookworm -> Trixie + block: + - name: Replace sources.list entries for Trixie + lineinfile: + path: /etc/apt/sources.list + regexp: "^deb " + line: "deb https://deb.debian.org/debian trixie main" + become: yes + + - name: Update cache for Trixie + apt: + update_cache: yes + force_apt_get: yes + + - name: Dist-upgrade to Trixie + apt: + upgrade: dist + force_apt_get: yes + register: trixie_upgrade + + - name: Reboot to apply Trixie + reboot: + reboot_timeout: 600 + test_command: whoami + when: + - trixie_upgrade.changed + - ansible_virtualization_type != "lxc" + when: ansible_distribution_release == "bookworm" + + become: yes + +# --- Move to Trixie sources.list.d layout --- +- name: Remove old sources.list.d + file: + path: /etc/apt/sources.list.d + state: absent + become: yes + +- name: Remove old sources.list + file: + path: /etc/apt/sources.list + state: absent + become: yes + +- name: Ensure sources.list.d directory exists + file: + path: /etc/apt/sources.list.d + state: directory + mode: 0755 + become: yes + +- name: Create Trixie sources.list.d + copy: + dest: /etc/apt/sources.list.d/debian.sources + content: | + Types: deb deb-src + URIs: https://deb.debian.org/debian + Suites: trixie trixie-updates trixie-backports + Components: main + Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg + + Types: deb deb-src + URIs: https://deb.debian.org/debian-security + Suites: trixie-security + Components: main + Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg + owner: root + group: root + mode: 0644 + become: yes + +- name: Update APT cache after moving to sources.list.d layout + apt: + update_cache: yes + force_apt_get: yes + become: yes + +- name: Find all EXTERNALLY-MANAGED files under /usr/lib/python* + find: + paths: /usr/lib + patterns: "EXTERNALLY-MANAGED" + file_type: file + recurse: yes + register: externally_managed_files + become: yes + +- name: Delete EXTERNALLY-MANAGED files + file: + path: "{{ item.path }}" + state: absent + loop: "{{ externally_managed_files.files }}" + when: externally_managed_files.matched > 0 + become: yes +# - name: Download Oh My Zsh installation script +# get_url: +# url: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh +# dest: /tmp/install_ohmyzsh.sh + +# - name: Run Oh My Zsh installation script +# become: no +# command: sh /tmp/install_ohmyzsh.sh --unattended +# register: ohmyzsh_result +# failed_when: "'FAILED' in ohmyzsh_result.stderr" + +# - name: Download zsh Dracula Theme +# become: no +# unarchive: +# src: https://github.com/dracula/zsh/archive/refs/heads/master.zip +# dest: "/tmp" +# remote_src: yes + +# - name: Download moe theme for zsh +# become: no +# get_url: +# url: https://git.comprofix.com/mmckinnon/dotfiles/raw/branch/master/oh-my-zsh/moe.zsh-theme +# dest: "/home/{{ ansible_user }}/.oh-my-zsh/themes" +# force: true + +# - name: Move zsh theme to correct folder +# become: no +# copy: +# src: /tmp/zsh-master/ +# dest: /home/{{ ansible_user }}/.oh-my-zsh/themes +# remote_src: yes + +# - name: Create vim config paths +# become: no +# file: +# path: "/home/{{ ansible_user }}/.vim/pack/themes/start/dracula" +# state: directory + +# - name: Download vim Dracula Theme +# become: no +# unarchive: +# src: https://github.com/dracula/vim/archive/refs/heads/master.zip +# dest: "/tmp" +# remote_src: yes + +# - name: Move vim theme to correct folder +# become: no +# copy: +# src: /tmp/vim-master/ +# dest: /home/{{ ansible_user }}/.vim/pack/themes/start/dracula +# remote_src: yes + +# - name: Get zsh config +# become: no +# get_url: +# url: https://git.comprofix.com/mmckinnon/dotfiles/raw/branch/master/zsh/zshrc +# dest: "/home/{{ ansible_user }}/.zshrc" +# force: true + +# - name: Get vim config +# become: no +# get_url: +# url: https://git.comprofix.com/mmckinnon/dotfiles/raw/branch/master/vim/vimrc +# dest: "/home/{{ ansible_user }}/.vimrc" +# force: true + +# - name: Set shell zsh +# user: +# name: "{{ ansible_user }}" +# shell: /bin/zsh + +# - name: Set moe theme for zsh +# become: no +# ansible.builtin.lineinfile: +# path: "/home/{{ansible_user}}/.zshrc" +# regexp: '^ZSH_THEME="dracula"' +# line: 'ZSH_THEME="moe"' + diff --git a/tasks/comprofix.com.yml b/tasks/comprofix.com.yml new file mode 100644 index 0000000..f9a5a5d --- /dev/null +++ b/tasks/comprofix.com.yml @@ -0,0 +1,14 @@ +- name: Create the comprofix.com container + docker_container: + name: comprofix.com + image: git.comprofix.com/mmckinnon/comprofix.com:latest + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + labels: + traefik.enable: "true" + traefik.http.routers.comprofix.rule: "Host(`comprofix.com`)" + traefik.http.routers.comprofix.entrypoints: "https" + traefik.http.routers.comprofix.tls: "true" + traefik.http.services.comprofix.loadbalancer.server.port: "80" \ No newline at end of file diff --git a/tasks/dozzle-agent.yml b/tasks/dozzle-agent.yml new file mode 100644 index 0000000..548746b --- /dev/null +++ b/tasks/dozzle-agent.yml @@ -0,0 +1,12 @@ +--- +- name: Create the dozzle container + docker_container: + name: dozzle_agent + image: amir20/dozzle:v8.13.12 + restart_policy: unless-stopped + command: agent + recreate: true + ports: + - 7007:7007 + volumes: + - /var/run/docker.sock:/var/run/docker.sock diff --git a/tasks/dozzle.yml b/tasks/dozzle.yml new file mode 100644 index 0000000..45fdbf9 --- /dev/null +++ b/tasks/dozzle.yml @@ -0,0 +1,29 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/dozzle" + - "{{ data_folder }}/dozzle/config" + +- name: Create the dozzle container + docker_container: + name: dozzle + image: amir20/dozzle:v8.13.12 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + volumes: + - /var/run/docker.sock:/var/run/docker.sock + env: + DOZZLE_LEVEL: "trace" + DOZZLE_REMOTE_AGENT: "omada-lxc.comprofix.xyz:7007" + labels: + traefik.enable: "true" + traefik.http.routers.dozzle.rule: "Host(`dozzle.comprofix.xyz`)" + traefik.http.routers.dozzle.entrypoints: "https" + traefik.http.routers.dozzle.tls: "true" + traefik.http.services.dozzle.loadbalancer.server.port: "8080" + traefik.http.services.dozzle.loadbalancer.server.scheme: "http" diff --git a/tasks/gitea-runner-homelab.yml b/tasks/gitea-runner-homelab.yml new file mode 100644 index 0000000..79c6e85 --- /dev/null +++ b/tasks/gitea-runner-homelab.yml @@ -0,0 +1,42 @@ +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/gitea-runner" + - "{{ data_folder }}/gitea-runner/config" + +- name: Check that config.yaml exists + stat: + path: "{{ data_folder }}/gitea-runner/config/config.yaml" + register: configyaml + +- name: Create config.yaml file + file: + path: "{{ data_folder }}/gitea-runner/config/config.yaml" + state: touch + mode: "0600" + access_time: preserve + modification_time: preserve + when: configyaml.stat.exists == False + +- name: Create the gitea-runner container + docker_container: + name: gitea-runner + image: gitea/act_runner:0.2.13 + restart_policy: unless-stopped + recreate: true + # dns_servers:a + # - 10.10.10.1 + # - 127.0.0.11 + volumes: + - "/etc/resolv.conf:/etc/resolv.conf:ro" + - /var/run/docker.sock:/var/run/docker.sock + - "{{ data_folder }}/gitea-runner/config/config.yaml:/config.yaml" + - "/etc/hosts:/etc/hosts:ro" + env: + CONFIG_FILE: "/config.yaml" + GITEA_INSTANCE_URL: "https://git.comprofix.com" + GITEA_RUNNER_REGISTRATION_TOKEN: "{{ GITEA_RUNNER_TOKEN }}" + GITEA_RUNNER_NAME: "homelab-runner" + GITEA_RUNNER_LABELS: "alpine-latest:docker://alpine:latest,ubuntu-latest:docker://node:22-trixie,homelab-latest:docker://git.comprofix.com/mmckinnon/debian-latest:2025.08.31-093853" diff --git a/tasks/gitea.yml b/tasks/gitea.yml new file mode 100644 index 0000000..1ea9cf1 --- /dev/null +++ b/tasks/gitea.yml @@ -0,0 +1,134 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/gitea" + - "{{ data_folder }}/gitea/data" + - "{{ data_folder }}/gitea/db" + +- name: Create MySQL DB for Gitea + docker_container: + name: gitea_db + image: mysql:9 + restart_policy: unless-stopped + networks: + - name: proxy + env: + MYSQL_ROOT_PASSWORD: "{{ gitea_db_root_password }}" + MYSQL_USER: "{{ gitea_db_user }}" + MYSQL_PASSWORD: "{{ gitea_db_password }}" + MYSQL_DATABASE: gitea + volumes: + - "{{ data_folder }}/gitea/db:/var/lib/mysql" + +- name: Create the Gitea container + docker_container: + name: gitea + image: gitea/gitea:1.24 + restart_policy: unless-stopped + recreate: true + # dns_servers: + # - 10.10.10.1 + # - 127.0.0.11 + networks: + - name: proxy + ports: + - "2222:22" + env: + PUID: "1001" + PGID: "1001" + TZ: "Australia/Brisbane" + volumes: + - "{{ data_folder }}/gitea/data:/data" + - "/etc/timezone:/etc/timezone:ro" + - "/etc/localtime:/etc/localtime:ro" + labels: + traefik.enable: "true" + traefik.http.routers.gitea.rule: "Host(`git.comprofix.com`)" + traefik.http.routers.gitea.entrypoints: "https" + traefik.http.routers.gitea.tls: "true" + traefik.http.routers.gitea.service: "gitea" + traefik.http.services.gitea.loadbalancer.server.port: "3000" + register: container_gitea + +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/gitea-runner" + - "{{ data_folder }}/gitea-runner/config" + +- name: Check that config.yaml exists + stat: + path: "{{ data_folder }}/gitea-runner/config/config.yaml" + register: configyaml + +- name: Create config.yaml file + file: + path: "{{ data_folder }}/gitea-runner/config/config.yaml" + state: touch + mode: "0600" + access_time: preserve + modification_time: preserve + when: configyaml.stat.exists == False + +- name: Create the gitea-runner container + docker_container: + name: gitea-runner + image: gitea/act_runner:0.2.13 + restart_policy: unless-stopped + recreate: true + # dns_servers: + # - 10.10.10.1 + # - 127.0.0.11 + volumes: + - "/etc/resolv.conf:/etc/resolv.conf:ro" + - /var/run/docker.sock:/var/run/docker.sock + - "{{ data_folder }}/gitea-runner/config/config.yaml:/config.yaml" + - "/etc/hosts:/etc/hosts:ro" + env: + CONFIG_FILE: "/config.yaml" + GITEA_INSTANCE_URL: "https://git.comprofix.com" + GITEA_RUNNER_REGISTRATION_TOKEN: "{{ GITEA_RUNNER_TOKEN }}" + GITEA_RUNNER_NAME: "gitea-runner" + GITEA_RUNNER_LABELS: "alpine-latest:docker://alpine:latest,ubuntu-latest:docker://node:22-trixie,vps-latest:docker://git.comprofix.com/mmckinnon/debian-latest:2025.08.31-093853" + +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/opengist" + +- name: Create the opengist container + docker_container: + name: opengist + image: ghcr.io/thomiceli/opengist:1.10 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + # dns_servers: + # - 10.10.10.1 + # - 127.0.0.11 + volumes: + - "{{ data_folder }}/opengist:/opengist" + env: + OG_GITEA_CLIENT_KEY: "{{ OG_GITEA_KEY }}" + OG_GITEA_SECRET: "{{ OG_GITEA_SECRET }}" + # URL of the Gitea instance. Default: https://gitea.com/ + OG_GITEA_URL: "https://git.comprofix.com" + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + labels: + traefik.enable: "true" + traefik.http.routers.opengist.rule: "Host(`gist.comprofix.com`)" + traefik.http.routers.opengist.entrypoints: "https" + traefik.http.routers.opengist.tls: "true" + traefik.http.routers.opengist.service: "opengist" + traefik.http.services.opengist.loadbalancer.server.port: "6157" + register: container diff --git a/tasks/gotify.yml b/tasks/gotify.yml new file mode 100644 index 0000000..6053144 --- /dev/null +++ b/tasks/gotify.yml @@ -0,0 +1,26 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/gotify" + - "{{ data_folder }}/gotify/data" + +- name: Create the gotify container + docker_container: + name: gotify + image: gotify/server:2.6.3 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + volumes: + - /data/gotify/data:/app/data + labels: + traefik.enable: "true" + traefik.http.routers.gotify.rule: "Host(`gotify.comprofix.com`)" + traefik.http.routers.gotify.entrypoints: "https" + traefik.http.routers.gotify.tls: "true" + traefik.http.routers.gotify.service: "gotify" + traefik.http.services.gotify.loadbalancer.server.port: "80" diff --git a/tasks/homepage.yml b/tasks/homepage.yml new file mode 100644 index 0000000..70364ef --- /dev/null +++ b/tasks/homepage.yml @@ -0,0 +1,40 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/homepage" + - "{{ data_folder }}/homepage/config" + +- name: Get dashboard-icons + git: + repo: https://github.com/walkxcode/dashboard-icons.git + dest: /data/dashboard-icons + update: yes + +- name: Create the homepage container + docker_container: + name: homepage + image: ghcr.io/gethomepage/homepage:v1.4.6 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + dns_servers: + - 10.10.10.1 + env: + LOG_LEVEL: debug + HOMEPAGE_ALLOWED_HOSTS: homepage.comprofix.xyz + volumes: + - "{{ data_folder }}/homepage/config:/app/config" + - "{{ data_folder }}/dashboard-icons:/app/public/icons" + - /var/run/docker.sock:/var/run/docker.sock + labels: + traefik.enable: "true" + traefik.http.routers.homepage.rule: "Host(`homepage.comprofix.xyz`)" + traefik.http.routers.homepage.entrypoints: "https" + traefik.http.routers.homepage.tls: "true" + traefik.http.routers.homepage.service: "homepage" + traefik.http.services.homepage.loadbalancer.server.port: "3000" + register: container_homepage diff --git a/tasks/idrac.yml b/tasks/idrac.yml new file mode 100644 index 0000000..528077d --- /dev/null +++ b/tasks/idrac.yml @@ -0,0 +1,15 @@ +--- +- name: Create the Dell_R730xd Fan Contoller container + docker_container: + name: Dell_R730xd + image: ghcr.io/tigerblue77/dell_idrac_fan_controller:latest@sha256:eda09016a4acbee8883996f3b8cd4832a723200999bd037934675e75e2f00908 + restart_policy: unless-stopped + recreate: true + env: + IDRAC_HOST: "10.10.10.105" + IDRAC_USERNAME: "root" + IDRAC_PASSWORD: "calvin" + FAN_SPEED: "40" + CPU_TEMPERATURE_THRESHOLD: "80" + CHECK_INTERVAL: "60" + DISABLE_THIRD_PARTY_PCIE_CARD_DELL_DEFAULT_COOLING_RESPONSE: "true" diff --git a/tasks/invoiceninja.yml b/tasks/invoiceninja.yml new file mode 100644 index 0000000..bc2c63c --- /dev/null +++ b/tasks/invoiceninja.yml @@ -0,0 +1,95 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/invoiceninja/" + - "{{ data_folder }}/invoiceninja/config" + - "{{ data_folder }}/invoiceninja/db" + +- name: "create stack.env" + copy: + dest: "{{ data_folder }}/invoiceninja/stack.env" + content: | + APP_NAME="Invoice Ninja" + APP_ENV=production + APP_KEY="{{ IN_APP_KEY }}" + APP_DEBUG=false + APP_URL="{{ IN_APP_URL }}" + REQUIRE_HTTPS=true + TRUSTED_PROXIES='*' + SESSION_ENCRYPT=false + SESSION_SECURE=false + DB_CONNECTION="mysql" + MULTI_DB_ENABLED=false + DB_HOST="{{MYSQL_HOST}}" + DB_DATABASE="{{IN_DB_DATABASE}}" + DB_USERNAME="{{IN_DB_USERNAME}}" + DB_PASSWORD="{{IN_DB_PASSWORD}}" + DB_PORT="3306" + DEMO_MODE=false + BROADCAST_DRIVER=log + LOG_CHANNEL=stack + CACHE_DRIVER=file + #QUEUE_CONNECTION=sync + QUEUE_CONNECTION=database + SESSION_DRIVER=file + SESSION_LIFETIME=120 + REDIS_HOST=127.0.0.1 + REDIS_PASSWORD=null + REDIS_PORT=6379 + MAIL_MAILER="smtp" + MAIL_HOST="{{MAIL_HOST}}" + MAIL_PORT="{{MAIL_PORT}}" + MAIL_ENCRYPTION="tls" + MAIL_FROM_ADDRESS="{{MAIL_FROM}}" + MAIL_FROM_NAME="{{MAIL_FROM_NAME}}" + POSTMARK_API_TOKEN= + GOOGLE_MAPS_API_KEY= + ERROR_EMAIL= + NINJA_ENVIRONMENT="selfhost" + #options - snappdf / phantom / hosted_ninja + PDF_GENERATOR=hosted_ninja + PHANTOMJS_KEY='a-demo-key-with-low-quota-per-ip-address' + PHANTOMJS_SECRET=secret + UPDATE_SECRET=secret + SENTRY_LARAVEL_DSN=https://32f01ea994744fa08a0f688769cef78a@sentry.invoicing.co/ + +- name: Create the invoiceninja-app container + docker_container: + name: invoiceninja-app + image: invoiceninja/invoiceninja:5 + env_file: "{{ data_folder }}/invoiceninja/stack.env" + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + volumes: + - "{{ data_folder }}/invoiceninja/config/hosts:/etc/hosts" + - "{{ data_folder }}/invoiceninja/docker/app/public:/var/www/app/public" + - "{{ data_folder }}/invoiceninja/docker/app/storage:/var/www/app/storage" + +- name: Create the invoiceninja-nginx container + docker_container: + name: invoiceninja-nginx + image: nginx:1.29.1 + env_file: "{{ data_folder }}/invoiceninja/stack.env" + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + volumes: + - "{{ data_folder }}/invoiceninja/config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf" + - "{{ data_folder }}/invoiceninja/docker/app/public:/var/www/app/public" + - "{{ data_folder }}/invoiceninja/docker/app/storage:/var/www/app/storage" + labels: + traefik.enable: "true" + traefik.http.routers.invoiceninja.rule: "Host(`invoice.comprofix.com`)" + traefik.http.routers.invoiceninja.entrypoints: "https" + traefik.http.routers.invoiceninja.tls: "true" + traefik.http.services.invoiceninja.loadbalancer.server.port: "80" + traefik.http.services.invoiceninja.loadbalancer.server.scheme: "http" + + + diff --git a/tasks/iscsi.yml b/tasks/iscsi.yml new file mode 100644 index 0000000..0a3787d --- /dev/null +++ b/tasks/iscsi.yml @@ -0,0 +1,88 @@ +--- +- name: Ensure open-iscsi is installed + package: + name: open-iscsi + state: present + +- name: Ensure parted is installed + package: + name: parted + state: present + +- name: Discover iSCSI targets + command: sudo iscsiadm -m discovery -t sendtargets -p "10.10.10.2" + register: iscsi_discovery + +- name: Set target_iqn variable based on discovery + set_fact: + target_iqn: "{{ item.split(' ')[1] }}" + loop: "{{ iscsi_discovery.stdout_lines }}" + when: item.startswith("10.10.10.2") + +- name: Check if iSCSI target is already connected + command: iscsiadm -m session + register: iscsi_sessions + changed_when: false + failed_when: iscsi_sessions.rc not in [0, 21] # Allow success if the return code is 0 or 21 + +- name: Connect to iSCSI target + command: sudo iscsiadm -m node -T "{{ target_iqn }}" -p "10.10.10.2" --login + when: target_iqn is defined and target_iqn not in iscsi_sessions.stdout + +- name: Set iSCSI target for automatic login + command: sudo iscsiadm -m node -T "{{ target_iqn }}" -p "10.10.10.2" --op update --name node.startup --value automatic + when: target_iqn is defined + +- name: Fail if no target_iqn found + fail: + msg: "No target IQN found for iSCSI server IP 10.10.10.2" + when: target_iqn is not defined + +- name: List all block devices + command: lsblk -o NAME,SIZE,TYPE,MODEL + register: lsblk_output + +- name: Set iSCSI device variable + set_fact: + iscsi_device: "/dev/{{ item.split()[0] }}" + loop: "{{ lsblk_output.stdout_lines }}" + when: item.split()[2] == 'disk' and 'iSCSI' in item # Adjust based on the MODEL you observe + +- name: Fail if no iSCSI device found + fail: + msg: "No iSCSI device found!" + when: iscsi_device is not defined + +- name: Create a partition on iSCSI device using parted + parted: + device: "{{ iscsi_device }}" + number: 1 + state: present + part_type: primary + fs_type: ext4 + part_start: 0% # Start at the beginning of the device + part_end: 100% # Use the entire available space + +- name: Create filesystem on new partition + filesystem: + fstype: ext4 + dev: "{{ iscsi_device }}1" # Format the partition + +- name: Create mount point + file: + path: /data + state: directory + +- name: Mount iSCSI target + mount: + path: /data + src: "{{ iscsi_device }}1" # Mount the new partition + fstype: ext4 + opts: defaults,_netdev + state: mounted + +# - name: Ensure iSCSI target is mounted at boot +# lineinfile: +# path: /etc/fstab +# line: "{{ iscsi_device }}1 /data ext4 _netdev 0 0" +# state: present diff --git a/tasks/jellyseerr.yml b/tasks/jellyseerr.yml new file mode 100644 index 0000000..8ce5134 --- /dev/null +++ b/tasks/jellyseerr.yml @@ -0,0 +1,29 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/jellyseerr" + - "{{ data_folder }}/jellyseerr/config" + +- name: Create the jellyseerr container + docker_container: + name: jellyseerr + image: fallenbagel/jellyseerr:2.7.3 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + volumes: + - "{{ data_folder }}/jellyseerr/config:/app/config" + labels: + traefik.enable: "true" + traefik.http.routers.jellyseerr.rule: "Host(`jellyseerr.comprofix.xyz`)" + traefik.http.routers.jellyseerr.entrypoints: "https" + traefik.http.routers.jellyseerr.tls: "true" + traefik.http.services.jellyseerr.loadbalancer.server.port: "5055" \ No newline at end of file diff --git a/tasks/lidarr.yml b/tasks/lidarr.yml new file mode 100644 index 0000000..6458aec --- /dev/null +++ b/tasks/lidarr.yml @@ -0,0 +1,36 @@ +--- +- name: Set Facts + set_fact: + container_name: 'lidarr' + +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/lidarr" + - "{{ data_folder }}/lidarr/config" + +- name: Create the lidarr container + docker_container: + name: lidarr + image: ghcr.io/linuxserver/lidarr:latest@sha256:186bc4d3f22bd6a71c235c1c7f57f90a8473f766278d9c929398fb5ce90eae7e + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + AUTO_UPDATE: "true" #optional + DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:lidarr" + volumes: + - "{{ data_folder }}/lidarr/config:/config" + - /mnt/nfs/data:/data + labels: + traefik.enable: "true" + traefik.http.routers.lidarr.rule: "Host(`lidarr.comprofix.xyz`)" + traefik.http.routers.lidarr.entrypoints: "https" + traefik.http.routers.lidarr.tls: "true" + traefik.http.services.lidarr.loadbalancer.server.port: "8686" diff --git a/tasks/mariadb.yml b/tasks/mariadb.yml new file mode 100644 index 0000000..908757e --- /dev/null +++ b/tasks/mariadb.yml @@ -0,0 +1,29 @@ +--- +- name: Set Facts + set_fact: + container_name: 'mariadb' + +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/mariadb" + - "{{ data_folder }}/mariadb/config" + +- name: Create the mariadb container + docker_container: + name: "mariadb" + image: ghcr.io/linuxserver/mariadb:11.4.8 + restart_policy: unless-stopped + recreate: true + ports: + - 3306:3306 + env: + PUID: "0" + PGID: "0" + MYSQL_ROOT_PASSWORD: "{{MYSQL_ROOT_PASSWORD}}" + TZ: "Australia/Brisbane" + volumes: + - "{{ data_folder }}/mariadb/config:/config" + \ No newline at end of file diff --git a/tasks/mealie.yml b/tasks/mealie.yml new file mode 100644 index 0000000..72d850d --- /dev/null +++ b/tasks/mealie.yml @@ -0,0 +1,36 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/mealie" + - "{{ data_folder }}/mealie/config" + +- name: Create the mealie container + docker_container: + name: mealie + image: ghcr.io/mealie-recipes/mealie:v3.1.2 + restart_policy: unless-stopped + networks: + - name: proxy + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + RECIPE_PUBLIC: "true" + RECIPE_SHOW_NUTRITION: "false" + RECIPE_SHOW_ASSETS: "true" + RECIPE_LANDSCAPE_VIEW: "true" + RECIPE_DISABLE_COMMENTS: "true" + RECIPE_DISABLE_AMOUNT: "true" + BASE_URL: "mealie.comprofix.xyz" + SMTP_HOST: "{{MAIL_HOST}}" + volumes: + - "{{ data_folder }}/mealie/data/:/app/data" + labels: + traefik.enable: "true" + traefik.http.routers.mealie.rule: "Host(`mealie.comprofix.xyz`)" + traefik.http.routers.mealie.entrypoints: "https" + traefik.http.routers.mealie.tls: "true" + traefik.http.services.mealie.loadbalancer.server.port: "9000" diff --git a/tasks/mediawiki.yml b/tasks/mediawiki.yml new file mode 100644 index 0000000..28781ab --- /dev/null +++ b/tasks/mediawiki.yml @@ -0,0 +1,29 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/mediawiki" + +- name: Create the wiki container + docker_container: + name: mediawiki + image: mediawiki:1.44.0 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + volumes: + - "{{ data_folder }}/mediawiki/images:/var/www/html/images" + - "{{ data_folder }}/mediawiki/LocalSettings.php:/var/www/html/LocalSettings.php" + labels: + traefik.enable: "true" + traefik.http.routers.wiki.rule: "Host(`wiki.comprofix.xyz`)" + traefik.http.routers.wiki.entrypoints: "https" + traefik.http.routers.wiki.tls: "true" + traefik.http.services.wiki.loadbalancer.server.port: "80" diff --git a/tasks/omada.yml b/tasks/omada.yml new file mode 100644 index 0000000..44ee97b --- /dev/null +++ b/tasks/omada.yml @@ -0,0 +1,24 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/omada" + - "{{ data_folder }}/omada/data" + - "{{ data_folder }}/omada/logs" + +- name: Create the omada container + docker_container: + name: omada + image: mbentley/omada-controller:5.15 + restart_policy: unless-stopped + recreate: true + network_mode: host + volumes: + - "{{ data_folder }}/omada/data:/opt/tplink/EAPController/data" + - "{{ data_folder }}/omada/logs:/opt/tplink/EAPController/logs" + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" diff --git a/tasks/osticket.yml b/tasks/osticket.yml new file mode 100644 index 0000000..1fcb232 --- /dev/null +++ b/tasks/osticket.yml @@ -0,0 +1,61 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/osticket" + - "{{ data_folder }}/osticket/config" + +- name: Create the osticket container + docker_container: + name: osticket + image: devinsolutions/osticket:1.17.5 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + SMTP_HOST: "{{MAIL_HOST}}" + MYSQL_HOST: "{{MYSQL_HOST}}" + MYSQL_DATABASE: "{{OST_DATABASE}}" + MYSQL_USER: "{{OST_DB_USER}}" + MYSQL_PASSWORD: "{{OST_DB_PASSWORD}}" + INSTALL_SECRET: "{{OST_SIRI}}" + labels: + traefik.enable: "true" + traefik.http.routers.osticket.rule: "Host(`helpdesk.comprofix.com`)" + traefik.http.routers.osticket.entrypoints: "https" + traefik.http.routers.osticket.tls: "true" + traefik.http.services.osticket.loadbalancer.server.port: "80" + traefik.http.services.osticket.loadbalancer.server.scheme: "http" + +- name: Add tzdata to osTicket container + community.docker.docker_container_exec: + container: osticket + command: apk add tzdata + +- name: Set container Timezone + community.docker.docker_container_exec: + container: osticket + command: "ln -s /usr/share/zoneinfo/Australia/Brisbane /etc/localtime" + +- name: Set PHP Timezone + community.docker.docker_container_exec: + container: osticket + command: "sed -i 's|UTC|Australia/Brisbane|g' /usr/local/etc/php/conf.d/php-osticket.ini" + +- name: Patch mysqli.php for timezone + community.docker.docker_container_exec: + container: osticket + command: "sed -i 's|system_time_zone|time_zone|g' /var/www/html/include/mysqli.php" + +- name: Clear ost_sessions table + mysql_query: + login_host: "{{MYSQL_HOST}}" + login_user: "{{OST_DB_USER}}" + login_password: "{{OST_DB_PASSWORD}}" + login_db: "{{OST_DATABASE}}" + query: + - USE comprofix_ost; + - TRUNCATE TABLE ost_session; diff --git a/tasks/postgres.yml b/tasks/postgres.yml new file mode 100644 index 0000000..a44e739 --- /dev/null +++ b/tasks/postgres.yml @@ -0,0 +1,22 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "/mnt/nfs/docker/postgres" + - "/mnt/nfs/docker/postgres/config" + +- name: Create the postgres container + docker_container: + name: postgres + image: postgres:16-alpine + restart_policy: unless-stopped + recreate: true + ports: + - 5432:5432 + env: + POSTGRES_PASSWORD: "{{POSTGRES_PASSWORD}}" + volumes: + - /mnt/nfs/docker/postgres/db-data:/var/lib/postgresql/data + diff --git a/tasks/prowlarr.yml b/tasks/prowlarr.yml new file mode 100644 index 0000000..10492e4 --- /dev/null +++ b/tasks/prowlarr.yml @@ -0,0 +1,31 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/prowlarr" + - "{{ data_folder }}/prowlarr/config" + +- name: Create the prowlarr container + docker_container: + name: prowlarr + image: linuxserver/prowlarr:2.0.5 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + AUTO_UPDATE: "true" #optional + DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:prowlarr" + volumes: + - "{{ data_folder }}/prowlarr/config:/config" + labels: + traefik.enable: "true" + traefik.http.routers.prowlarr.rule: "Host(`prowlarr.comprofix.xyz`)" + traefik.http.routers.prowlarr.entrypoints: "https" + traefik.http.routers.prowlarr.tls: "true" + traefik.http.services.prowlarr.loadbalancer.server.port: "9696" diff --git a/tasks/pykms.yml b/tasks/pykms.yml new file mode 100644 index 0000000..53243eb --- /dev/null +++ b/tasks/pykms.yml @@ -0,0 +1,26 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/pykms" + - "{{ data_folder }}/pykms/db" + +- name: Create the pykms container + docker_container: + name: pykms + image: ghcr.io/py-kms-organization/py-kms:latest + restart_policy: unless-stopped + recreate: true + ports: + - "1688:1688" + env: + IP: "0.0.0.0" + SQLITE: "true" + HWID: "RANDOM" + LOGLEVEL: "INFO" + volumes: + - "{{ data_folder }}/pykms/db:/home/py-kms/db" + - /etc/localtime:/etc/localtime:ro + diff --git a/tasks/radarr.yml b/tasks/radarr.yml new file mode 100644 index 0000000..33dd265 --- /dev/null +++ b/tasks/radarr.yml @@ -0,0 +1,31 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/radarr" + - "{{ data_folder }}/radarr/config" + +- name: Create the radarr container + docker_container: + name: radarr + image: linuxserver/radarr:5.27.5 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:radarr" + volumes: + - "{{ data_folder }}/radarr/config:/config" + - /mnt/nfs/data:/data + labels: + traefik.enable: "true" + traefik.http.routers.radarr.rule: "Host(`radarr.comprofix.xyz`)" + traefik.http.routers.radarr.entrypoints: "https" + traefik.http.routers.radarr.tls: "true" + traefik.http.services.radarr.loadbalancer.server.port: "7878" \ No newline at end of file diff --git a/tasks/readarr.yml b/tasks/readarr.yml new file mode 100644 index 0000000..dd7b1eb --- /dev/null +++ b/tasks/readarr.yml @@ -0,0 +1,33 @@ +# Readarr has been archived/retired. +# Keeping this for history +# --- +# - name: Create directories +# file: +# path: "{{ item }}" +# state: directory +# with_items: +# - "{{ data_folder }}/readarr" +# - "{{ data_folder }}/readarr/config" + +# - name: Create the readarr container +# docker_container: +# name: readarr +# image: linuxserver/readarr:develop@sha256:eb37f58646a901dc7727cf448cae36daaefaba79de33b5058dab79aa4c04aefb +# restart_policy: unless-stopped +# recreate: true +# networks: +# - name: proxy +# env: +# PUID: "1000" +# PGID: "1000" +# TZ: "Australia/Brisbane" +# DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:readarr" +# volumes: +# - "{{ data_folder }}/readarr/config/:/config" +# - /mnt/nfs/data/:/data +# labels: +# traefik.enable: "true" +# traefik.http.routers.readarr.rule: "Host(`readarr.comprofix.xyz`)" +# traefik.http.routers.readarr.entrypoints: "https" +# traefik.http.routers.readarr.tls: "true" +# traefik.http.services.readarr.loadbalancer.server.port: "8787" diff --git a/tasks/sabnzbd.yml b/tasks/sabnzbd.yml new file mode 100644 index 0000000..5ad241a --- /dev/null +++ b/tasks/sabnzbd.yml @@ -0,0 +1,32 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/sabnzbd" + - "{{ data_folder }}/sabnzbd/config" + +- name: Create the sabnzbd container + docker_container: + name: sabnzbd + image: linuxserver/sabnzbd:4.5.3 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + HOSTNAME: "sabnzbd.comprofix.xyz" + DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:sabnzbd" + volumes: + - "{{ data_folder }}/sabnzbd/config:/config" + - /mnt/nfs/data:/data + labels: + traefik.enable: "true" + traefik.http.routers.sabnzbd.rule: "Host(`sabnzbd.comprofix.xyz`)" + traefik.http.routers.sabnzbd.entrypoints: "https" + traefik.http.routers.sabnzbd.tls: "true" + traefik.http.services.sabnzbd.loadbalancer.server.port: "8080" diff --git a/tasks/sonarr.yml b/tasks/sonarr.yml new file mode 100644 index 0000000..7f28d8f --- /dev/null +++ b/tasks/sonarr.yml @@ -0,0 +1,31 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/sonarr" + - "{{ data_folder }}/sonarr/config" + +- name: Create the sonarr container + docker_container: + name: sonarr + image: linuxserver/sonarr:4.0.15 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + DOCKER_MODS: "ghcr.io/themepark-dev/theme.park:sonarr" + volumes: + - "{{ data_folder }}/sonarr/config/:/config" + - /mnt/nfs/data:/data + labels: + traefik.enable: "true" + traefik.http.routers.sonarr.rule: "Host(`sonarr.comprofix.xyz`)" + traefik.http.routers.sonarr.entrypoints: "https" + traefik.http.routers.sonarr.tls: "true" + traefik.http.services.sonarr.loadbalancer.server.port: "8989" diff --git a/tasks/speedtest.yml b/tasks/speedtest.yml new file mode 100644 index 0000000..183916e --- /dev/null +++ b/tasks/speedtest.yml @@ -0,0 +1,41 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/speedtest" + - "{{ data_folder }}/speedtest/config" + - "{{ data_folder }}/speedtest/web" + +- name: Create the speedtest container + docker_container: + name: speedtest + image: lscr.io/linuxserver/speedtest-tracker:1.6.6 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + APP_KEY: "base64:ViJcK7rSIwGC+TAW7pRWnczB43zPPVHH2Hx80t7eVm0=" + PUID: "1000" + PGID: "1000" + DB_CONNECTION: "mysql" + DB_HOST: "{{ MYSQL_HOST }}" + DB_PORT: "3306" + DB_DATABASE: "{{ST_DATABASE}}" + DB_USERNAME: "{{ST_DB_USERNAME}}" + DB_PASSWORD: "{{ST_DB_PASSWORD}}" + TZ: "Australia/Brisbane" + SPEEDTEST_SCHEDULE: "0 * * * *" + DISPLAY_TIMEZONE: "Australia/Brisbane" + volumes: + - "{{ data_folder }}/speedtest/config:/config" + - "{{ data_folder }}/speedtest/web:/etc/ssl/web" + labels: + traefik.enable: "true" + traefik.http.routers.speedtest.rule: "Host(`speedtest.comprofix.xyz`)" + traefik.http.routers.speedtest.entrypoints: "https" + traefik.http.routers.speedtest.tls: "true" + traefik.http.services.speedtest.loadbalancer.server.port: "80" + traefik.http.services.speedtest.loadbalancer.server.scheme: "http" diff --git a/tasks/traggo.yml b/tasks/traggo.yml new file mode 100644 index 0000000..a446934 --- /dev/null +++ b/tasks/traggo.yml @@ -0,0 +1,26 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/traggo" + - "{{ data_folder }}/traggo/data" + +- name: Create the traggo container + docker_container: + name: traggo + image: traggo/server:0.7.1 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + volumes: + - /data/traggo/data:/opt/traggo/data + labels: + traefik.enable: "true" + traefik.http.routers.traggo.rule: "Host(`traggo.comprofix.xyz`)" + traefik.http.routers.traggo.entrypoints: "https" + traefik.http.routers.traggo.tls: "true" + traefik.http.services.traggo.loadbalancer.server.port: "3030" + traefik.http.services.traggo.loadbalancer.server.scheme: "http" diff --git a/tasks/vaultwarden.yml b/tasks/vaultwarden.yml new file mode 100644 index 0000000..87795f1 --- /dev/null +++ b/tasks/vaultwarden.yml @@ -0,0 +1,64 @@ +--- +- name: Create directories + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ data_folder }}/vaultwarden" + - "{{ data_folder }}/vaultwarden/config" + - "{{ data_folder }}/vaultwardenbackup" + - "{{ data_folder }}/vaultwardenbackup/config" + - "{{ data_folder }}/vaultwardenbackup/config/rclone" + +- name: Create the vaultwarden container + docker_container: + name: vaultwarden + image: vaultwarden/server:1.34.3 + restart_policy: unless-stopped + recreate: true + networks: + - name: proxy + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + volumes: + - "{{ data_folder }}/vaultwarden/data:/data" + labels: + traefik.enable: "true" + traefik.http.routers.vaultwarden.rule: "Host(`vault.comprofix.com`)" + traefik.http.routers.vaultwarden.entrypoints: "https" + traefik.http.routers.vaultwarden.tls: "true" + traefik.http.routers.vaultwarden.service: "vaultwarden" + traefik.http.services.vaultwarden.loadbalancer.server.port: "80" + register: container + +- name: Copy rclone config + copy: + src: scripts/rclone.conf + dest: "{{ data_folder }}/vaultwardenbackup/config/rclone/rclone.conf" + decrypt: yes + mode: "0600" + +- name: Create the vaultwarden container + docker_container: + name: vaultwardenbackup + image: ttionya/vaultwarden-backup:1.25.1 + restart_policy: unless-stopped + recreate: true + env: + PUID: "1000" + PGID: "1000" + TZ: "Australia/Brisbane" + CRON: "0 4 * * *" + BACKUP_KEEP_DAYS: "14" + ZIP_PASSWORD: "{{ VAULTWARDEN_BACKUP_ZIP_PASSWORD }}" + volumes: + - "{{ data_folder }}/vaultwarden/data:/bitwarden/data" + - "{{ data_folder }}/vaultwardenbackup/config:/config" + register: container + + + + + diff --git a/vault.sh b/vault.sh new file mode 100755 index 0000000..e2803e8 --- /dev/null +++ b/vault.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# If number of arguments is 0 +if [ $# -eq 0 ] + then + echo "This script will encrypt of decrypt all files containing secrets." + echo "There are all files in vars as well as all secrets.yaml files under each service." + echo "Specify 'decrypt' or 'encrypt' as argument" + echo "If you put the vault password in a password file named .vault_password, the script will not ask for a password." + exit 1 +fi + +#files=`find . \( -type d -name 'group_vars' -o -name 'vars' \) -exec find {} -type f \;` +files=( + "./group_vars/all.yml" + "./roles/docker/vars/main.yml" + "./roles/traefik/vars/main.yml" + "./scripts/rclone.conf" +) + +# password_type=--ask-vault-password +# if [ -f "~/.vault_password.txt" ] +# then +# if [ `stat -c %a ~/.vault_password.txt` != "600" ] +# then +# echo "~/.vault_password.txt file has bad permissions; fixing this to 600" +# chmod 600 ~/.vault_password.txt +# fi +# password_type="--vault-password-file=~/.vault_password.txt" +# fi + +if [ $1 == "encrypt" ] + then + for file in "${files[@]}"; do + echo "$file encrypted" + ansible-vault encrypt --vault-password-file=~/.vault_password "$file" + echo $value; + done + +elif [ $1 == "decrypt" ] + then + for file in "${files[@]}"; do + echo "$file decrypted" + ansible-vault decrypt --vault-password-file=~/.vault_password "$file" + done +else + echo "Wrong argument supplied. Run without arguments to see allowed ones." +fi