commit 0ab1c043d611bcc5748096f60a991536b2e2e658 Author: TuDatTr Date: Wed Nov 30 23:49:07 2022 +0100 Initial commit with not yet working docker networking Signed-off-by: TuDatTr diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..580dcf8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/secrets.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c1b98e --- /dev/null +++ b/README.md @@ -0,0 +1,59 @@ +# TuDatTr IaC +## Vault +- Create vault with: `ansible-vault create secrets.yml` +- Create entry in vault with: `ansible-vault edit secrets.yml` +- Add entry: `pi_tudattr_password: YOUR_USERS_PASSWORD` +- Add entry: `aya01_tudattr_password: YOUR_USERS_PASSWORD` + +## Server +- Install Debian (debian-11.5.0-amd64-netinst.iso) on remote system +- Create user (tudattr) +- Get IP of remote system (192.168.20.11) +- Create ssh-config entry + ```config + Host aya01 + HostName 192.168.20.11 + Port 22 + User tudattr + IdentityFile /mnt/veracrypt1/genesis + ``` + - copy public key to remote system + `ssh-copy-id -i /mnt/veracrypt1/genesis.pub aya01` +- Adjust ansible inventory +- Install sudo on remote +- add user to sudo group (with `su --login` without login the path will not be loaded correctly see [here](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=918754)) and `usermod -a -G sudo tudattr` +- set time correctly when getting the following error +```sh +Release file for http://security.debian.org/debian-security/dists/bullseye-security/InRelease is not valid yet (invalid for another 12h 46min 9s). Updates for this repository will not be applied. +``` +By doing on remote system (example): + +## RaspberryPi +- Install raspbian lite (2022-09-22-raspios-bullseye-arm64-lite.img) on pi +- Get IP of remote system (192.168.20.11) +- Create ssh-config entry +```config +Host pi + HostName 192.168.20.11 + Port 22 + User tudattr + IdentityFile /mnt/veracrypt1/genesis +``` +- enable ssh on pi +- copy public key to pi +- change user password of user on pi +- execute `ansible-galaxy install geerlingguy.docker` +- execute `ansible-playbook -i production --ask-vault-pass --extra-vars '@secrets.yml' pi.yml` + +## Mikrotik +- Create rsa-key on your device and name it mikrotik_rsa +- On mikrotik run: `/user/ssh-keys/import public-key-file=mikrotik_rsa.pub user=tudattr` +- Create ssh-config entry: +```config +Host mikrotik + HostName 192.168.70.1 + Port 2200 + User tudattr + IdentityFile /mnt/veracrypt1/mikrotik_rsa +``` + diff --git a/aya01.yml b/aya01.yml new file mode 100644 index 0000000..214aeb9 --- /dev/null +++ b/aya01.yml @@ -0,0 +1,7 @@ +--- +- name: Set up Servers + hosts: server + gather_facts: yes + roles: + - role: common + - role: power_management diff --git a/group_vars/all/vars.yml b/group_vars/all/vars.yml new file mode 100644 index 0000000..8891754 --- /dev/null +++ b/group_vars/all/vars.yml @@ -0,0 +1,29 @@ +# +# Essential +# +user: tudattr +timezone: Europe/Berlin +local_domain: borg.land + +# +# Packages +# +common_packages: + - sudo + - git + - iperf3 + - git + - tmux + - smartmontools + +# +# Docker +# +docker_repo_url: https://download.docker.com/linux +docker_apt_gpg_key: "{{ docker_repo_url }}/{{ ansible_distribution | lower }}/gpg" +docker_apt_release_channel: stable +docker_apt_arch: "{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}" +docker_apt_repository: "deb [arch={{ docker_apt_arch }}] {{ docker_repo_url }}/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} {{ docker_apt_release_channel }}" + +docker_compose_dir: /opt/docker/compose +docker_dir: /opt/docker/config diff --git a/host_vars/aya01.yml b/host_vars/aya01.yml new file mode 100644 index 0000000..3f7a8b7 --- /dev/null +++ b/host_vars/aya01.yml @@ -0,0 +1,6 @@ +ansible_user: "{{ user }}" +ansible_host: 192.168.20.12 +ansible_port: 22 +ansible_ssh_private_key_file: /mnt/veracrypt1/genesis +ansible_become_pass: '{{ aya01_tudattr_password }}' + diff --git a/host_vars/pi.yml b/host_vars/pi.yml new file mode 100644 index 0000000..60974a2 --- /dev/null +++ b/host_vars/pi.yml @@ -0,0 +1,5 @@ +ansible_user: "{{ user }}" +ansible_host: 192.168.20.11 +ansible_port: 22 +ansible_ssh_private_key_file: /mnt/veracrypt1/genesis +ansible_become_pass: '{{ pi_tudattr_password }}' diff --git a/host_vars/vagrant.yml b/host_vars/vagrant.yml new file mode 100644 index 0000000..8662183 --- /dev/null +++ b/host_vars/vagrant.yml @@ -0,0 +1,4 @@ +ansible_user: vagrant +ansible_host: 127.0.0.1 +ansible_port: 2222 +ansible_ssh_private_key_file: .vagrant/machines/vagrant/virtualbox/private_key diff --git a/pi.yml b/pi.yml new file mode 100644 index 0000000..436024c --- /dev/null +++ b/pi.yml @@ -0,0 +1,7 @@ +--- +- name: Set up Raspberry Pis + hosts: raspberry + gather_facts: yes + roles: + - common + - docker diff --git a/production b/production new file mode 100644 index 0000000..05997fa --- /dev/null +++ b/production @@ -0,0 +1,5 @@ +[server] +aya01 + +[raspberry] +pi diff --git a/roles/common/tasks/essential.yml b/roles/common/tasks/essential.yml new file mode 100644 index 0000000..c0b2bd7 --- /dev/null +++ b/roles/common/tasks/essential.yml @@ -0,0 +1,13 @@ +--- +- name: Update and upgrade packages + apt: + update_cache: yes + upgrade: yes + autoremove: yes + become: yes + +- name: Install extra packages + apt: + name: "{{ common_packages }}" + state: present + become: yes diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml new file mode 100644 index 0000000..1cea739 --- /dev/null +++ b/roles/common/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- include_tasks: time.yml +- include_tasks: essential.yml diff --git a/roles/common/tasks/time.yml b/roles/common/tasks/time.yml new file mode 100644 index 0000000..7e216ed --- /dev/null +++ b/roles/common/tasks/time.yml @@ -0,0 +1,4 @@ +--- +- name: Set timezone to "{{ timezone }}" + community.general.timezone: + name: "{{ timezone }}" diff --git a/roles/docker/tasks/compose.yml b/roles/docker/tasks/compose.yml new file mode 100644 index 0000000..5a371ba --- /dev/null +++ b/roles/docker/tasks/compose.yml @@ -0,0 +1,54 @@ +--- +- name: Create ddns-config directory + file: + path: "{{ docker_dir }}/ddns-updater/data/" + owner: 1000 + mode: '700' + state: directory + +- name: Copy ddns-config + template: + owner: 1000 + src: "templates/ddns-updater/data/config.json" + dest: "{{ docker_dir }}/ddns-updater/data/config.json" + mode: '400' + +- name: Create traefik-config directory + file: + path: "{{ docker_dir }}/traefik/" + owner: 1000 + mode: '700' + state: directory + +- name: Create pihole-config directory + file: + path: "{{ item }}" + owner: 1000 + mode: '777' + state: directory + loop: + - "{{ docker_dir }}/pihole/etc-pihole/" + - "{{ docker_dir }}/pihole/etc-dnsmasq.d/" + become: yes + +- name: Copy traefik-config + template: + owner: 1000 + src: "templates/traefik/traefik.yml" + dest: "{{ docker_dir }}/traefik/traefik.yml" + mode: '400' + +- name: Shut down docker + shell: + cmd: "docker compose down --remove-orphans" + chdir: "{{ docker_compose_dir }}" + +- name: Copy the compose file + template: + src: templates/compose.yaml + dest: "{{ docker_compose_dir }}/compose.yaml" + +- name: Run docker compose + shell: + cmd: "docker compose up -d" + chdir: "{{ docker_compose_dir }}" diff --git a/roles/docker/tasks/install.yml b/roles/docker/tasks/install.yml new file mode 100644 index 0000000..50b555e --- /dev/null +++ b/roles/docker/tasks/install.yml @@ -0,0 +1,67 @@ +--- +- name: Uninstall old versions + apt: + name: "{{ item }}" + state: absent + purge: true + loop: + - docker + - docker-engine + - docker.io + - containerd + - runc + become: true + +- name: Update cache + apt: + update_cache: true + become: true + +- name: Install dependencies for apt to use repositories over HTTPS + apt: + name: "{{ item }}" + state: present + loop: + - ca-certificates + - curl + - gnupg + - lsb-release + become: true + +- name: Create keyrings direcoty + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + mode: '0755' + become: true + +- 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: true + become: true + +- name: Add Docker repository. + apt_repository: + repo: "{{ docker_apt_repository }}" + state: present + become: true + +- name: Update cache + apt: + update_cache: true + become: true + +- name: Install Docker Engine, containerd, and Docker Compose. + apt: + name: "{{ item }}" + state: present + loop: + - docker-ce + - docker-ce-cli + - docker-compose-plugin + - containerd.io + become: true + diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml new file mode 100644 index 0000000..5b9edcd --- /dev/null +++ b/roles/docker/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- include_tasks: install.yml +- include_tasks: user_group_setup.yml +- include_tasks: compose.yml + diff --git a/roles/docker/tasks/user_group_setup.yml b/roles/docker/tasks/user_group_setup.yml new file mode 100644 index 0000000..e0cab68 --- /dev/null +++ b/roles/docker/tasks/user_group_setup.yml @@ -0,0 +1,25 @@ +--- +- name: Ensure group "docker" exists + group: + name: docker + state: present + become: yes + +- name: Append the group "docker" to "{{ user }}" groups + ansible.builtin.user: + name: "{{ user }}" + shell: /bin/bash + groups: docker + append: yes + become: yes + +- name: Make sure that the docker folders exists + ansible.builtin.file: + path: "{{ item }}" + owner: "{{ user }}" + group: "{{ user }}" + state: directory + loop: + - "{{docker_compose_dir}}" + - "{{docker_dir}}" + become: yes diff --git a/roles/docker/templates/compose.yaml b/roles/docker/templates/compose.yaml new file mode 100644 index 0000000..a6108c7 --- /dev/null +++ b/roles/docker/templates/compose.yaml @@ -0,0 +1,85 @@ +version: '3' +services: + traefik: + container_name: traefik + image: traefik:v2.5 + networks: + - compose_net + volumes: + - "/etc/localtime:/etc/localtime:ro" + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - {{ docker_dir }}/traefik/traefik.yml:/etc/traefik/traefik.yml + ports: + - 80:80 + - 8080:8080 + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.rule=Host(`traefik.{{local_domain}}`)" + - "traefik.http.routers.traefik.entrypoints=web" + - "traefik.http.services.traefik.loadbalancer.server.port=80" + ddns-updater: + container_name: ddns-updater + image: "ghcr.io/qdm12/ddns-updater" + networks: + - compose_net + volumes: + - {{ docker_dir }}/ddns-updater/data/:/updater/data/ + ports: + - 8000:8000/tcp + restart: unless-stopped + homeassistant: + container_name: homeassistant + image: "ghcr.io/home-assistant/home-assistant:stable" + networks: + - compose_net + volumes: + - /etc/localtime:/etc/localtime:ro + - {{ docker_dir }}/home-assistant/config/:/config/ + restart: unless-stopped + privileged: true + network_mode: host + labels: + - "traefik.enable=true" + - "traefik.http.routers.homeassistant.rule=Host(`hass.{{local_domain}}`)" + - "traefik.http.routers.homeassistant.entrypoints=web" + - "traefik.http.services.homeassistant.loadbalancer.server.port=8123" + pihole: + container_name: pihole + image: pihole/pihole:latest + networks: + - compose_net + ports: + - "53:53/tcp" + - "53:53/udp" + - "67:67/udp" + - "8089:80/tcp" + environment: + - "TZ=Europe/Berlin" + - "WEBPASSWORD=a" + - "ServerIP=192.168.20.11" + - "INTERFACE=eth0" + - "DNS1=1.1.1.1" + - "DNS1=1.0.0.1" + volumes: + - "{{ docker_dir }}/pihole/etc-pihole/:/etc/pihole/" + - "{{ docker_dir }}/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" + dns: + - 127.0.0.1 + - 1.1.1.1 + cap_add: + - NET_ADMIN + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.http.routers.pihole.rule=Host(`pihole.{{local_domain}}`)" + - "traefik.http.routers.pihole.entrypoints=web" + - "traefik.http.services.pihole.loadbalancer.server.port=8089" + +networks: + compose_net: + driver: bridge + ipam: + driver: default + config: + - subnet: 172.16.69.0/24 + gateway: 172.16.69.1 diff --git a/roles/docker/templates/ddns-updater/data/config.json b/roles/docker/templates/ddns-updater/data/config.json new file mode 100644 index 0000000..2ab8f73 --- /dev/null +++ b/roles/docker/templates/ddns-updater/data/config.json @@ -0,0 +1,31 @@ +{ + "settings": [ + { + "provider": "namecheap", + "domain": "tudattr.dev", + "host": "@", + "password": "f12ffc0d94dd4bbdb862fcf2c0bed864", + "provider_ip": true + }, { + "provider": "namecheap", + "domain": "tudattr.dev", + "host": "www", + "password": "f12ffc0d94dd4bbdb862fcf2c0bed864", + "provider_ip": true + }, + { + "provider": "namecheap", + "domain": "tudattr.dev", + "host": "plex", + "password": "f12ffc0d94dd4bbdb862fcf2c0bed864", + "provider_ip": true + }, + { + "provider": "namecheap", + "domain": "borg.land", + "host": "@", + "password": "aae80116bf684d4abbadbbb37b36d391", + "provider_ip": true + } + ] +} diff --git a/roles/docker/templates/traefik/traefik.yml b/roles/docker/templates/traefik/traefik.yml new file mode 100644 index 0000000..0aeb4f4 --- /dev/null +++ b/roles/docker/templates/traefik/traefik.yml @@ -0,0 +1,16 @@ +## traefik.yml +# Entry Points +entryPoints: + web: + address: ":80" + websecure: + address: ":443" + +# Docker configuration backend +providers: + docker: + defaultRule: "Host(`{{ '{{' }} trimPrefix `/` .Name {{ '}}' }}.{{ local_domain }}`)" + +# API and dashboard configuration +api: + insecure: true diff --git a/roles/power_management/tasks/configure.yml b/roles/power_management/tasks/configure.yml new file mode 100644 index 0000000..3599eb4 --- /dev/null +++ b/roles/power_management/tasks/configure.yml @@ -0,0 +1,24 @@ +--- +- name: Copy powertop service + template: + src: templates/powertop.service + dest: /etc/systemd/system/powertop.service + become: true + +- name: Reload all services + ansible.builtin.systemd: + daemon_reload: yes + become: true + +- name: Start and enable the new powertop service + ansible.builtin.systemd: + state: started + enabled: true + name: powertop + become: true + +- name: Copy hdparm.conf + template: + src: templates/hdparm.conf + dest: /etc/hdparm.conf + become: true diff --git a/roles/power_management/tasks/install.yml b/roles/power_management/tasks/install.yml new file mode 100644 index 0000000..77aff65 --- /dev/null +++ b/roles/power_management/tasks/install.yml @@ -0,0 +1,15 @@ +--- +- name: Update cache + apt: + update_cache: true + become: true + +- name: Install packages + apt: + name: "{{ item }}" + state: present + loop: + - powertop + - hdparm + become: true + diff --git a/roles/power_management/tasks/main.yml b/roles/power_management/tasks/main.yml new file mode 100644 index 0000000..bca1e74 --- /dev/null +++ b/roles/power_management/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- include_tasks: install.yml +- include_tasks: configure.yml diff --git a/roles/power_management/templates/hdparm.conf b/roles/power_management/templates/hdparm.conf new file mode 100644 index 0000000..102d763 --- /dev/null +++ b/roles/power_management/templates/hdparm.conf @@ -0,0 +1,18 @@ +quiet +/dev/sda { + apm = 128 + spindown_time = 240 +} + +/dev/sdb { + apm = 128 + spindown_time = 240 +} +/dev/sdc { + apm = 128 + spindown_time = 240 +} +/dev/sdd { + apm = 128 + spindown_time = 240 +} \ No newline at end of file diff --git a/roles/power_management/templates/powertop.service b/roles/power_management/templates/powertop.service new file mode 100644 index 0000000..2fc5ac7 --- /dev/null +++ b/roles/power_management/templates/powertop.service @@ -0,0 +1,11 @@ +[Unit] +Description=PowerTOP auto tune + +[Service] +Type=oneshot +Environment="TERM=dumb" +RemainAfterExit=true +ExecStart=/usr/sbin/powertop --auto-tune + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/staging b/staging new file mode 100644 index 0000000..f7644c9 --- /dev/null +++ b/staging @@ -0,0 +1,2 @@ +[server] +vagrant \ No newline at end of file