It's a start
This commit is contained in:
parent
302b725dc1
commit
e1a9018ca6
34 changed files with 774 additions and 1 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Specify filepatterns you want git to ignore.
|
||||||
|
|
||||||
|
.env
|
||||||
|
|
@ -17,4 +17,4 @@ The needed parts as of right now
|
||||||
- Ansible
|
- Ansible
|
||||||
- To automate the software layers and container deployments
|
- To automate the software layers and container deployments
|
||||||
- PXE
|
- PXE
|
||||||
- For local cloud-init? with OpenTofu? (still researching this
|
- For local cloud-init? with OpenTofu? (still researching this)
|
||||||
|
|
|
||||||
1
ansible/phiax.nl/testicle/README.rst
Normal file
1
ansible/phiax.nl/testicle/README.rst
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Is this file needed?
|
||||||
6
ansible/phiax.nl/testicle/galaxy.yml
Normal file
6
ansible/phiax.nl/testicle/galaxy.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace: phiax.nl
|
||||||
|
name: testicle
|
||||||
|
version: 1.0.0
|
||||||
|
author: Frank "PHiAX" Weggelaar
|
||||||
|
description: Ansible collection for doing all the things.
|
||||||
|
dependencies: []
|
||||||
5
ansible/phiax.nl/testicle/inventory/main.yaml
Normal file
5
ansible/phiax.nl/testicle/inventory/main.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
raspberries:
|
||||||
|
hosts:
|
||||||
|
app-octoprint.phiax.nl:
|
||||||
|
sensor-adsb.phiax.nl:
|
||||||
|
|
||||||
21
ansible/phiax.nl/testicle/playbooks/install_octoprint.yml
Normal file
21
ansible/phiax.nl/testicle/playbooks/install_octoprint.yml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
vars_prompt:
|
||||||
|
- name: "install_dir"
|
||||||
|
prompt: "Install directory"
|
||||||
|
private: false
|
||||||
|
default: "/opt/OctoPrint"
|
||||||
|
- name: "new_hostname"
|
||||||
|
prompt: "Hostname"
|
||||||
|
private: false
|
||||||
|
default: "octoprint.local"
|
||||||
|
- name: "appport"
|
||||||
|
prompt: "OctoPrint listening Port"
|
||||||
|
private: false
|
||||||
|
default: 5000
|
||||||
|
- name: "webcam_port"
|
||||||
|
prompt: "Webcam listening Port"
|
||||||
|
private: false
|
||||||
|
default: 8080
|
||||||
|
roles:
|
||||||
|
- octoprint
|
||||||
29
ansible/phiax.nl/testicle/playbooks/install_raspberry.yml
Normal file
29
ansible/phiax.nl/testicle/playbooks/install_raspberry.yml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
# Notice that "# noqa: package-latest" is included in this file. This disabled a specific check for the Ansible linter,
|
||||||
|
# see: https://ansible.readthedocs.io/projects/lint/usage/#muting-warnings-to-avoid-false-positives.
|
||||||
|
# For a purely reproducible build this would be a good suggestion but I'm willing to take the risk with the Pi.
|
||||||
|
- name: Install raspberry pi
|
||||||
|
hosts: all
|
||||||
|
# vars_files:
|
||||||
|
# - vault.yml
|
||||||
|
# - versions.yml
|
||||||
|
roles:
|
||||||
|
# These roles are disabled after they have being applied once for performance reasons, it should be safe to enable them again.
|
||||||
|
# Notice that this role changes some settings on reruns (on the "Change various sysctl-settings" task), doesn't seem problematic though.
|
||||||
|
- role: devsec.hardening.ssh_hardening
|
||||||
|
become: true
|
||||||
|
- role: packages
|
||||||
|
become: true
|
||||||
|
vars:
|
||||||
|
# devsec.hardening.ssh_hardening vars:
|
||||||
|
ssh_client_port: 22 # Default, but duplicated here for documentation purpose. Not changed because its only accessible via LAN.
|
||||||
|
ssh_client_password_login: false # Default, but duplicated here for documentation purpose.
|
||||||
|
ssh_allow_tcp_forwarding: true
|
||||||
|
tasks:
|
||||||
|
# This task can be handy for debugging gathered facts, uncomment it if necessary:
|
||||||
|
# - name: Store gathered facts in local file
|
||||||
|
# delegate_to: localhost
|
||||||
|
# ansible.builtin.copy:
|
||||||
|
# dest: './.ansible_facts.json'
|
||||||
|
# content: "{{ ansible_facts }}"
|
||||||
|
# mode: "0600"
|
||||||
20
ansible/phiax.nl/testicle/playbooks/omz.yaml
Normal file
20
ansible/phiax.nl/testicle/playbooks/omz.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
- hosts: all
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- role: system/ohmyzsh
|
||||||
|
vars:
|
||||||
|
target_user: "phiax"
|
||||||
|
ohmyzsh_theme: "agnoster"
|
||||||
|
ohmyzsh_plugins:
|
||||||
|
- git
|
||||||
|
- zsh-autosuggestions
|
||||||
|
http_fetcher: "curl"
|
||||||
|
|
||||||
|
####
|
||||||
|
# Notes:
|
||||||
|
#
|
||||||
|
# Role creates .oh-my-zsh by running upstream installer as the target user (RUNZSH=no, KEEP_ZSHRC=yes).
|
||||||
|
# Override variables in playbook/inventory to target different users, themes, or plugin lists.
|
||||||
|
# For systems where zsh path differs, override zsh_path.
|
||||||
|
#
|
||||||
|
####
|
||||||
13
ansible/phiax.nl/testicle/playbooks/requirements.yml
Normal file
13
ansible/phiax.nl/testicle/playbooks/requirements.yml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
collections:
|
||||||
|
# See: https://galaxy.ansible.com/ui/repo/published/devsec/hardening/
|
||||||
|
- name: devsec.hardening
|
||||||
|
version: 10.3.0
|
||||||
|
# See: https://galaxy.ansible.com/ui/repo/published/prometheus/prometheus/
|
||||||
|
# Docs: https://prometheus-community.github.io/ansible/branch/main/prometheus_role.html#ansible-collections-prometheus-prometheus-prometheus-role
|
||||||
|
- name: prometheus.prometheus
|
||||||
|
version: 0.26.0
|
||||||
|
roles:
|
||||||
|
# See: https://galaxy.ansible.com/ui/standalone/roles/geerlingguy/docker/
|
||||||
|
- name: geerlingguy.docker
|
||||||
|
version: 7.4.7
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
- name Backup Mikrotik Device Configs
|
||||||
|
hosts switches
|
||||||
|
gather_facts no
|
||||||
|
tasks
|
||||||
|
- name Fetch running config
|
||||||
|
mikrotik.cli_command
|
||||||
|
commands /export compact
|
||||||
|
register output
|
||||||
|
|
||||||
|
- name Save config to file
|
||||||
|
copy
|
||||||
|
content {{ output.stdout[0] }}
|
||||||
|
dest backups{{ inventory_hostname }}.cfg
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- global
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
---
|
||||||
|
- name: Create new user
|
||||||
|
user: name={{ new_username }}
|
||||||
|
password={{ new_password |password_hash('sha512') }}
|
||||||
|
state=present
|
||||||
|
update_password=on_create
|
||||||
|
shell=/bin/bash
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
|
||||||
|
- name: Copy sudoer dropin file
|
||||||
|
template: src=sudoers_dropin.j2
|
||||||
|
dest=/etc/sudoers.d/{{ new_username }}
|
||||||
|
owner=root
|
||||||
|
group=root
|
||||||
|
mode="0600"
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
|
||||||
|
- name: Add public ssh key to new users authorized key list
|
||||||
|
authorized_key: user={{ username }}
|
||||||
|
key="{{ lookup('file', ssh_pub_key) }}"
|
||||||
|
state=present
|
||||||
|
become: yes
|
||||||
|
become_user: "{{ new_username }}"
|
||||||
|
when: add_ssh_pub_key |bool
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Defaults>{{ new_username }} !lecture
|
||||||
|
{{ new_username }} ALL=(ALL) NOPASSWD:ALL
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
- name: Configure hostname
|
||||||
|
become: true
|
||||||
|
ansible.builtin.hostname:
|
||||||
|
name: "{{ hostname }}"
|
||||||
|
- name: Remove existing /etc/hosts entry for hostname and add FQDN name
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/hosts
|
||||||
|
regexp: "^127.0.1.1.*$"
|
||||||
|
line: "127.0.0.1 {{ hostname }}.phiax.nl {{ hostname }}"
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- global
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
- name: Set static ip address (replace /etc/dhcpcd.conf)
|
||||||
|
template: src=etc_dhcpcd.conf.j2
|
||||||
|
dest=/etc/dhcpcd.conf
|
||||||
|
backup=yes
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
# A sample configuration for dhcpcd.
|
||||||
|
# See dhcpcd.conf(5) for details.
|
||||||
|
|
||||||
|
# Allow users of this group to interact with dhcpcd via the control socket.
|
||||||
|
#controlgroup wheel
|
||||||
|
|
||||||
|
# Inform the DHCP server of our hostname for DDNS.
|
||||||
|
hostname
|
||||||
|
|
||||||
|
# Use the hardware address of the interface for the Client ID.
|
||||||
|
clientid
|
||||||
|
# or
|
||||||
|
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
|
||||||
|
#duid
|
||||||
|
|
||||||
|
# Persist interface configuration when dhcpcd exits.
|
||||||
|
persistent
|
||||||
|
|
||||||
|
# Rapid commit support.
|
||||||
|
# Safe to enable by default because it requires the equivalent option set
|
||||||
|
# on the server to actually work.
|
||||||
|
option rapid_commit
|
||||||
|
|
||||||
|
# A list of options to request from the DHCP server.
|
||||||
|
option domain_name_servers, domain_name, domain_search, host_name
|
||||||
|
option classless_static_routes
|
||||||
|
# Most distributions have NTP support.
|
||||||
|
option ntp_servers
|
||||||
|
# Respect the network MTU.
|
||||||
|
# Some interface drivers reset when changing the MTU so disabled by default.
|
||||||
|
#option interface_mtu
|
||||||
|
|
||||||
|
# A ServerID is required by RFC2131.
|
||||||
|
require dhcp_server_identifier
|
||||||
|
|
||||||
|
# Generate Stable Private IPv6 Addresses instead of hardware based ones
|
||||||
|
slaac private
|
||||||
|
|
||||||
|
# A hook script is provided to lookup the hostname if not set by the DHCP
|
||||||
|
# server, but it should not be run by default.
|
||||||
|
nohook lookup-hostname
|
||||||
|
|
||||||
|
interface {{iface}}
|
||||||
|
static ip_address={{new_ip_address}}
|
||||||
|
static routers={{gateway_address}}
|
||||||
|
static domain_name_servers={{dns_address}}
|
||||||
|
|
||||||
117
ansible/phiax.nl/testicle/roles/helpers/user/tasks/main.yml
Normal file
117
ansible/phiax.nl/testicle/roles/helpers/user/tasks/main.yml
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
---
|
||||||
|
# The ZSH installation instructions are sourced from this blog:
|
||||||
|
# https://harshithashok.com/tools/oh-my-zsh-with-starship/
|
||||||
|
- name: Create the user
|
||||||
|
when: user_username is not undefined # Skip when no user is provided, we'll asume we're targetting the Ansible user.
|
||||||
|
block:
|
||||||
|
- name: Create a new user
|
||||||
|
become: true
|
||||||
|
ansible.builtin.user:
|
||||||
|
append: true
|
||||||
|
groups:
|
||||||
|
- users
|
||||||
|
name: "{{ user_username }}"
|
||||||
|
# Salt is necessary, see: https://stackoverflow.com/questions/56869949/ansible-user-module-always-shows-changed
|
||||||
|
password: "{{ user_password | password_hash('sha512', password_salt) }}"
|
||||||
|
- name: Ensure .ssh directory exists in user home
|
||||||
|
become: true
|
||||||
|
become_user: "{{ user_username }}"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/home/{{ user_username }}/.ssh"
|
||||||
|
state: directory
|
||||||
|
mode: "0700"
|
||||||
|
# We're assuming that the ansible user has its authorized keys setup before running the playbook and that all created users using this
|
||||||
|
# rule want the same machines to be able to access them.
|
||||||
|
- name: Copy over authorized keys from the main ansible user
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
remote_src: true
|
||||||
|
src: "/home/{{ ansible_facts['user_id'] }}/.ssh/authorized_keys"
|
||||||
|
dest: "/home/{{ user_username }}/.ssh/"
|
||||||
|
owner: "{{ user_username }}"
|
||||||
|
group: "{{ user_username }}"
|
||||||
|
mode: "0600"
|
||||||
|
- name: Set fact for defining the user which should run the next modules
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
target_user: "{{ ansible_facts['user_id'] if user_username is undefined else user_username }}"
|
||||||
|
# The "lingering" property seems to be important to Podman, otherwise errors are thrown as mentioned here:
|
||||||
|
# https://superuser.com/questions/1788594/podman-the-cgroupv2-manager-is-set-to-systemd-but-there-is-no-systemd-user-sess
|
||||||
|
- name: "Check if lingering is enabled (user: {{ target_user }})"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "loginctl show-user {{ target_user }} --property=Linger"
|
||||||
|
register: linger_check
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
- name: "Enable systemd \"lingering\" (user: {{ target_user }})"
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "loginctl enable-linger {{ target_user }}"
|
||||||
|
when: linger_check.rc != 0
|
||||||
|
changed_when: true
|
||||||
|
- name: Ensuring ZSH is installed
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt:
|
||||||
|
pkg:
|
||||||
|
- acl # Needed to prevent this error: https://stackoverflow.com/questions/46352173/ansible-failed-to-set-permissions-on-the-temporary
|
||||||
|
- zsh
|
||||||
|
state: present
|
||||||
|
- name: Install Oh My ZSH # noqa: command-instead-of-module ignore error since we're removing the script after install.
|
||||||
|
become: true
|
||||||
|
become_user: "{{ target_user }}"
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
|
||||||
|
chmod u+x install.sh
|
||||||
|
./install.sh --unattended
|
||||||
|
rm install.sh
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
creates: ~/.oh-my-zsh
|
||||||
|
- name: Install Starship # noqa: command-instead-of-module ignore error since we're removing the script after install.
|
||||||
|
become: true
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
wget https://starship.rs/install.sh
|
||||||
|
chmod u+x install.sh
|
||||||
|
./install.sh --yes
|
||||||
|
rm install.sh
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
creates: /usr/local/bin/starship
|
||||||
|
- name: Install zsh-autosuggestions # noqa: command-instead-of-module ignore error since we're removing the script after install.
|
||||||
|
become: true
|
||||||
|
become_user: "{{ target_user }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
|
||||||
|
creates: ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
|
||||||
|
- name: Clear "ZSH_THEME" in ~/.zshrc
|
||||||
|
become: true
|
||||||
|
become_user: "{{ target_user }}"
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: ~/.zshrc
|
||||||
|
regexp: '^ZSH_THEME="[^"]+"$'
|
||||||
|
line: ZSH_THEME=""
|
||||||
|
- name: Add the zsh-autosuggestions plugin in ~/.zshrc
|
||||||
|
become: true
|
||||||
|
become_user: "{{ target_user }}"
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: ~/.zshrc
|
||||||
|
regexp: '^plugins=\((.*)(?<!zsh-autosuggestions)\)$'
|
||||||
|
line: 'plugins=(\1 zsh-autosuggestions)'
|
||||||
|
backrefs: true
|
||||||
|
# For some reason snap isn't properly configured and its bin directory isn't added to the $PATH variable.
|
||||||
|
# This probably has something to do with the hardening rules, instead we'll fix it here.
|
||||||
|
- name: Add Starship config and Snapcraft to ~/.zshrc
|
||||||
|
become: true
|
||||||
|
become_user: "{{ target_user }}"
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: ~/.zshrc
|
||||||
|
block: |-
|
||||||
|
# Add Snapcraft to $PATH
|
||||||
|
export PATH=$PATH:/snap/bin
|
||||||
|
|
||||||
|
# Starship
|
||||||
|
eval "$(starship init zsh)"
|
||||||
|
- name: Change the default shell of the current user
|
||||||
|
become: true
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ target_user }}"
|
||||||
|
shell: /usr/bin/zsh
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
user_add_to_docker_group: false
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
- name: Confirm Certbot plugin containment level
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: snap set certbot trust-plugin-with-root=ok
|
||||||
|
- name: Restart Nginx
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: nginx.service
|
||||||
|
state: restarted
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
---
|
||||||
|
- name: Add an apt key by id from a keyserver
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt_key:
|
||||||
|
url: https://nginx.org/keys/nginx_signing.key
|
||||||
|
state: present
|
||||||
|
- name: Add Nginx repository into sources list
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: deb https://nginx.org/packages/debian/ {{ ansible_facts['lsb']['codename'] }} nginx
|
||||||
|
state: present
|
||||||
|
- name: Add Nginx source repository into sources list
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: deb-src https://nginx.org/packages/debian/ {{ ansible_facts['lsb']['codename'] }} nginx
|
||||||
|
state: present
|
||||||
|
- name: Install Nginx
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: nginx # Creates the "nginx" user as well
|
||||||
|
state: present
|
||||||
|
- name: Remove default configuration
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/nginx/conf.d/default.conf
|
||||||
|
state: absent
|
||||||
|
notify: Restart Nginx
|
||||||
|
# ---------- CERTBOT INSTALLATION ---------- #
|
||||||
|
# See the installation instructions here: https://certbot.eff.org/instructions?ws=nginx&os=debianbuster&tab=wildcard
|
||||||
|
- name: Install Certbot
|
||||||
|
become: true
|
||||||
|
community.general.snap:
|
||||||
|
name: certbot
|
||||||
|
classic: true
|
||||||
|
state: present
|
||||||
|
notify: Confirm Certbot plugin containment level
|
||||||
|
- name: Flush handlers # Makes sure that the handler runs
|
||||||
|
ansible.builtin.meta: flush_handlers
|
||||||
|
- name: Install Certbot DNS Cloudflare plugin
|
||||||
|
become: true
|
||||||
|
community.general.snap:
|
||||||
|
name: certbot-dns-cloudflare
|
||||||
|
classic: true
|
||||||
|
state: present
|
||||||
|
- name: Set cloudflare variable
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
cloudflare_credential_dir_path: "/root/.secrets/certbot"
|
||||||
|
cloudflare_credential_filename: cloudflare.ini
|
||||||
|
- name: Create Certbot credential directory
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ cloudflare_credential_dir_path }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0700'
|
||||||
|
- name: Place cloudflare credential in certbot user's file
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: cloudflare.ini.j2
|
||||||
|
dest: "{{ cloudflare_credential_dir_path }}/{{ cloudflare_credential_filename }}"
|
||||||
|
mode: '0400'
|
||||||
|
- name: Install the certificate script
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: register_certbot_domain.sh.j2
|
||||||
|
dest: /usr/local/bin/register_certbot_domain.sh
|
||||||
|
mode: '0500'
|
||||||
|
- name: Create the root certificate for my domain
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: register_certbot_domain.sh kleinendorst.info
|
||||||
|
creates: /etc/letsencrypt/live/kleinendorst.info # The certificate directory
|
||||||
|
# END ------ CERTBOT INSTALLATION ------ END #
|
||||||
|
- name: Start Nginx
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: nginx.service
|
||||||
|
state: started
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Cloudflare API token used by Certbot
|
||||||
|
dns_cloudflare_api_token = {{ dns_cloudflare_token }}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# For the --post-hook argument see: https://stackoverflow.com/questions/70002636/https-certbot-certificate-is-renewed-but-connection-not-secure-till-you-restart
|
||||||
|
/snap/bin/certbot certonly \
|
||||||
|
--dns-cloudflare \
|
||||||
|
--dns-cloudflare-propagation-seconds 120 \
|
||||||
|
--dns-cloudflare-credentials '{{ cloudflare_credential_dir_path }}/{{ cloudflare_credential_filename }}' \
|
||||||
|
--post-hook "nginx -s reload" \
|
||||||
|
--agree-tos -m {{ administration_email }} \
|
||||||
|
-d $1
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
nginx_user: nginx # Created automatically by the apt installation
|
||||||
|
certbot_user: certbot
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- global
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
- name: Installing required packages for haproxy
|
||||||
|
apt: name={{item}}
|
||||||
|
state=latest
|
||||||
|
with_items:
|
||||||
|
- haproxy
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- haproxy
|
||||||
|
|
||||||
|
- name: Copy haproxy.cfg
|
||||||
|
template: src=haproxy.cfg.j2
|
||||||
|
dest=/etc/haproxy/haproxy.cfg
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- haproxy
|
||||||
|
|
||||||
|
- name: Update /etc/default/haproxy
|
||||||
|
lineinfile:
|
||||||
|
dest: /etc/default/haproxy
|
||||||
|
state: present
|
||||||
|
regexp: '^#?\s*ENABLED\s*=\s*'
|
||||||
|
line: 'ENABLED=1'
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- haproxy
|
||||||
|
|
||||||
|
- name: Enable and start haproxy service
|
||||||
|
service: name=haproxy
|
||||||
|
enabled=yes
|
||||||
|
state=started
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- haproxy
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
---
|
||||||
|
- name: Gather the package facts
|
||||||
|
ansible.builtin.package_facts:
|
||||||
|
manager: auto
|
||||||
|
|
||||||
|
- name: Check whether a package called git is installed
|
||||||
|
apt: name={{item}}
|
||||||
|
state=latest
|
||||||
|
update_cache=yes
|
||||||
|
with_items:
|
||||||
|
- git
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
when: "'git' not in ansible_facts.packages"
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
virtualenv_dir: "{{ install_dir }}/.venv"
|
||||||
|
|
||||||
|
- name: Setting new hostname
|
||||||
|
hostname: name={{ new_hostname }}
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- init
|
||||||
|
|
||||||
|
- name: Create OctoPrint user group
|
||||||
|
group: name=OctoPrint
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
|
||||||
|
- name: Add user {{ username }} to OctoPrint group
|
||||||
|
user: name={{ username }}
|
||||||
|
groups=OctoPrint
|
||||||
|
append=yes
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
|
||||||
|
- name: Installing required packages
|
||||||
|
apt: name={{item}}
|
||||||
|
state=latest
|
||||||
|
update_cache=yes
|
||||||
|
with_items:
|
||||||
|
- python3-virtualenv
|
||||||
|
- python3-pip
|
||||||
|
- python3
|
||||||
|
- avahi-daemon
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- init
|
||||||
|
|
||||||
|
- name: Create {{ install_dir }} directory
|
||||||
|
file: path={{ install_dir }}
|
||||||
|
mode=0755
|
||||||
|
state=directory
|
||||||
|
owner={{ username }}
|
||||||
|
group=OctoPrint
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- init
|
||||||
|
|
||||||
|
- name: Download OctoPrint source
|
||||||
|
git: repo=https://github.com/foosel/OctoPrint.git
|
||||||
|
dest={{ install_dir }}
|
||||||
|
become: yes
|
||||||
|
become_user: "{{ username }}"
|
||||||
|
tags:
|
||||||
|
- code
|
||||||
|
|
||||||
|
- stat: path={{ virtualenv_dir }}/bin/activate
|
||||||
|
register: virtualenv_stats
|
||||||
|
tags:
|
||||||
|
- code
|
||||||
|
|
||||||
|
- name: Create virtualenv {{ virtualenv_dir }} (if it does not already exist)
|
||||||
|
command: "{{item}}"
|
||||||
|
with_items:
|
||||||
|
- virtualenv --prompt="(OctoPrint) " {{ virtualenv_dir }}
|
||||||
|
become: yes
|
||||||
|
become_user: "{{ username }}"
|
||||||
|
when: not virtualenv_stats.stat.exists
|
||||||
|
tags:
|
||||||
|
- code
|
||||||
|
|
||||||
|
- name: Update pip
|
||||||
|
pip: name=pip
|
||||||
|
state=latest
|
||||||
|
virtualenv={{ virtualenv_dir }}
|
||||||
|
become: yes
|
||||||
|
become_user: "{{ username }}"
|
||||||
|
tags:
|
||||||
|
- code
|
||||||
|
|
||||||
|
- name: Install OctoPrint
|
||||||
|
pip: name={{ install_dir }}
|
||||||
|
virtualenv={{ virtualenv_dir }}
|
||||||
|
extra_args="-e "
|
||||||
|
become: yes
|
||||||
|
become_user: "{{ username }}"
|
||||||
|
ignore_errors: yes
|
||||||
|
tags:
|
||||||
|
- code
|
||||||
|
|
||||||
|
- name: Install OctoPrint systemd Unit
|
||||||
|
template: src=octoprint.service.j2
|
||||||
|
dest=/etc/systemd/system/octoprint.service
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- service
|
||||||
|
|
||||||
|
- name: reload systemd
|
||||||
|
command: systemctl daemon-reload
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- service
|
||||||
|
|
||||||
|
- name: Enable and start OctoPrint service
|
||||||
|
service: name=octoprint
|
||||||
|
enabled=yes
|
||||||
|
state=restarted
|
||||||
|
become: yes
|
||||||
|
become_method: sudo
|
||||||
|
tags:
|
||||||
|
- service
|
||||||
|
|
||||||
|
- include_tasks: haproxy.yml
|
||||||
|
- include_tasks: webcam.yml
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
---
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
global
|
||||||
|
maxconn 4096
|
||||||
|
user haproxy
|
||||||
|
group haproxy
|
||||||
|
daemon
|
||||||
|
log 127.0.0.1 local0 debug
|
||||||
|
|
||||||
|
defaults
|
||||||
|
log global
|
||||||
|
mode http
|
||||||
|
option httplog
|
||||||
|
option dontlognull
|
||||||
|
retries 3
|
||||||
|
option redispatch
|
||||||
|
option http-server-close
|
||||||
|
option forwardfor
|
||||||
|
maxconn 2000
|
||||||
|
timeout connect 5s
|
||||||
|
timeout client 15m
|
||||||
|
timeout server 15m
|
||||||
|
|
||||||
|
frontend public
|
||||||
|
bind :::80 v4v6
|
||||||
|
use_backend webcam if { path_beg /webcam/ }
|
||||||
|
default_backend octoprint
|
||||||
|
|
||||||
|
backend octoprint
|
||||||
|
http-request replace-path ^([^\ :]*)\ /(.*) \1\ /\2
|
||||||
|
option forwardfor
|
||||||
|
server octoprint1 127.0.0.1:{{ appport }}
|
||||||
|
|
||||||
|
backend webcam
|
||||||
|
http-request replace-path ^([^\ :]*)\ /webcam/(.*) \1\ /\2
|
||||||
|
server webcam1 127.0.0.1:{{ webcam_port }}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
[Unit]
|
||||||
|
Description=OctoPrint
|
||||||
|
Requires=network.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Environment=PORT={{ appport }}
|
||||||
|
Environment=BASEDIR={{ install_dir }}/.octoprint
|
||||||
|
Environment=CONFIGFILE={{ install_dir }}/.octoprint/config.yaml
|
||||||
|
User={{ username }}
|
||||||
|
Group=OctoPrint
|
||||||
|
Nice=-2
|
||||||
|
ExecStart={{ virtualenv_dir }}/bin/octoprint serve --basedir ${BASEDIR} --config ${CONFIGFILE} --port ${PORT}
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Frank "PHiAX" Weggelaar
|
||||||
|
description: Install zsh and oh-my-zsh for a given user
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: 2.9
|
||||||
|
dependencies: []
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
---
|
||||||
|
- name: Ensure zsh is installed
|
||||||
|
package:
|
||||||
|
name: "{{ zsh_package | default('zsh') }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Ensure git is installed (required for oh-my-zsh)
|
||||||
|
package:
|
||||||
|
name: "{{ git_package | default('git') }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Ensure curl or wget is installed
|
||||||
|
package:
|
||||||
|
name: "{{ http_fetcher_package | default('curl') }}"
|
||||||
|
state: present
|
||||||
|
when: http_fetcher is not defined or http_fetcher == 'curl'
|
||||||
|
|
||||||
|
- name: Ensure wget is installed (if selected)
|
||||||
|
package:
|
||||||
|
name: "{{ http_fetcher_package | default('wget') }}"
|
||||||
|
state: present
|
||||||
|
when: http_fetcher == 'wget'
|
||||||
|
|
||||||
|
- name: Create zsh user config directory
|
||||||
|
file:
|
||||||
|
path: "{{ ansible_user_dir | default('/home/' + (ansible_user_id | default(ansible_user))) }}/.oh-my-zsh"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ target_user | default(ansible_user_id | default(ansible_user)) }}"
|
||||||
|
group: "{{ target_group | default(target_user | default(ansible_user_id | default(ansible_user))) }}"
|
||||||
|
mode: "0755"
|
||||||
|
become: true
|
||||||
|
when: not oh_my_zsh_custom_install
|
||||||
|
|
||||||
|
- name: Install oh-my-zsh (unattended) via curl
|
||||||
|
become: true
|
||||||
|
become_user: "{{ target_user | default(ansible_user_id | default(ansible_user)) }}"
|
||||||
|
shell: |
|
||||||
|
export RUNZSH=no
|
||||||
|
export KEEP_ZSHRC=yes
|
||||||
|
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||||
|
args:
|
||||||
|
creates: "{{ ansible_user_dir | default('/home/' + (ansible_user_id | default(ansible_user))) }}/.oh-my-zsh"
|
||||||
|
when:
|
||||||
|
- not oh_my_zsh_custom_install
|
||||||
|
- http_fetcher is not defined or http_fetcher == 'curl'
|
||||||
|
|
||||||
|
- name: Install oh-my-zsh (unattended) via wget
|
||||||
|
become: true
|
||||||
|
become_user: "{{ target_user | default(ansible_user_id | default(ansible_user)) }}"
|
||||||
|
shell: |
|
||||||
|
export RUNZSH=no
|
||||||
|
export KEEP_ZSHRC=yes
|
||||||
|
sh -c "$(wget -qO- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
|
||||||
|
args:
|
||||||
|
creates: "{{ ansible_user_dir | default('/home/' + (ansible_user_id | default(ansible_user))) }}/.oh-my-zsh"
|
||||||
|
when:
|
||||||
|
- not oh_my_zsh_custom_install
|
||||||
|
- http_fetcher == 'wget'
|
||||||
|
|
||||||
|
- name: Ensure .zshrc exists
|
||||||
|
copy:
|
||||||
|
dest: "{{ ansible_user_dir | default('/home/' + (ansible_user_id | default(ansible_user))) }}/.zshrc"
|
||||||
|
content: |
|
||||||
|
export ZSH="{{ ansible_user_dir | default('/home/' + (ansible_user_id | default(ansible_user))) }}/.oh-my-zsh"
|
||||||
|
ZSH_THEME="{{ ohmyzsh_theme | default('robbyrussell') }}"
|
||||||
|
plugins=({{ ohmyzsh_plugins | default(['git']) | join(' ') }})
|
||||||
|
source $ZSH/oh-my-zsh.sh
|
||||||
|
owner: "{{ target_user | default(ansible_user_id | default(ansible_user)) }}"
|
||||||
|
group: "{{ target_group | default(target_user | default(ansible_user_id | default(ansible_user))) }}"
|
||||||
|
mode: "0644"
|
||||||
|
force: no
|
||||||
|
|
||||||
|
- name: Change default shell to zsh for user
|
||||||
|
user:
|
||||||
|
name: "{{ target_user | default(ansible_user_id | default(ansible_user)) }}"
|
||||||
|
shell: "{{ zsh_path | default('/bin/zsh') }}"
|
||||||
|
become: true
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
# Defaults you can override in playbook or inventory
|
||||||
|
zsh_package: "zsh"
|
||||||
|
git_package: "git"
|
||||||
|
http_fetcher: "curl" # or "wget"
|
||||||
|
http_fetcher_package: "{{ 'curl' if http_fetcher == 'curl' else 'wget' }}"
|
||||||
|
ohmyzsh_theme: "robbyrussell"
|
||||||
|
ohmyzsh_plugins:
|
||||||
|
- git
|
||||||
|
target_user: "{{ lookup('env','SUDO_USER') | default(ansible_user_id | default(ansible_user)) }}"
|
||||||
|
target_group: "{{ target_user }}"
|
||||||
|
zsh_path: "/bin/zsh"
|
||||||
|
oh_my_zsh_custom_install: false # set true if you will manage oh-my-zsh yourself
|
||||||
22
docker/calibre.yaml
Normal file
22
docker/calibre.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
########################################################################
|
||||||
|
# #
|
||||||
|
# Description: Calibre-Web is a self-hosted e-book manager #
|
||||||
|
# ReferenceURL: https://docs.linuxserver.io/images/docker-calibre-web/ #
|
||||||
|
# #
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
services:
|
||||||
|
calibre-web:
|
||||||
|
image: lscr.io/linuxserver/calibre-web:latest
|
||||||
|
container_name: calibre-web
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- TZ=Europe/Amsterdam
|
||||||
|
- OAUTHLIB_RELAX_TOKEN_SCOPE=1 #optional
|
||||||
|
volumes:
|
||||||
|
- /path/to/calibre-web/data:/config
|
||||||
|
- /path/to/calibre/library:/books
|
||||||
|
ports:
|
||||||
|
- 8083:8083
|
||||||
|
restart: unless-stopped
|
||||||
Loading…
Add table
Add a link
Reference in a new issue