Fix linting and add backup cron job (#25)

pull/27/head
Cian Hatton 3 years ago committed by GitHub
parent d49819acec
commit 5cd48b220f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,3 @@
skip_list:
- '403' # allow for latest packages
- name[casing]

@ -20,10 +20,12 @@ jobs:
- uses: actions/setup-python@v4
with:
python-version: 3.8.9
- name: Create Vault Key
run: echo "${{ secrets.VAULT_PASSWORD }}" > ~/.vault-key
- name: Install dependencies
run: make deps
- name: Test Directory
run: ansible-lint ${{ matrix.directory }}
run: ansible-lint ${{ matrix.directory }} --exclude roles/sprat.mergerfs --exclude roles/docker_restore_container
format:
runs-on: ubuntu-latest

@ -25,7 +25,7 @@ format:
lint:
ansible-lint host_vars
ansible-lint group_vars
ansible-lint roles
ansible-lint roles --exclude roles/sprat.mergerfs --exclude roles/docker_restore_container
ansible-lint playbooks
backup: deps
@ -33,3 +33,6 @@ backup: deps
restore: deps
ansible-playbook playbooks/restore-docker-volumes.yml
cron:
ansible-playbook playbooks/setup-homelab.yml --tags cron

@ -2,21 +2,20 @@
vault_file: vault_vars/linode-vault.yml
# any linode specific variables go here
services:
- name: gitea
- name: mealie
- name: linkding
- name: overseerr
- name: nextcloud
- name: nginx-proxy-manager
- name: uptime-kuma
#- name: docker-volume-backup
- name: mariadb
- name: photoprism
- name: olivetin
- name: gitea
- name: mealie
- name: linkding
- name: overseerr
- name: nextcloud
- name: nginx-proxy-manager
- name: uptime-kuma
- name: mariadb
- name: photoprism
- name: olivetin
# any additional docker networks that should be created
docker_networks:
- mariadb_net
- mariadb_net
# use docker compose
container_deployment_mode: compose

@ -23,15 +23,15 @@ configure_samba: true
samba_group: smbgroup
samba_user: smbuser
users:
- name: cianhatton
group: cianhatton
passwordless_sudo: true
- name: cianhatton
group: cianhatton
passwordless_sudo: true
shares:
- /share
- /share/public_files
- /share/private_files
- /share/cian_files
- /share
- /share/public_files
- /share/private_files
- /share/cian_files
directories:
# path on qnap where downloads go
@ -50,5 +50,5 @@ directories:
photoprism_dir: /mnt/mergerfs/photoprism
desired_docker_images:
- ubuntu:latest
- busybox:latest
- ubuntu:latest
- busybox:latest

@ -2,58 +2,56 @@
vault_file: vault_vars/qnap-vault.yml
# any qnap specific variables go here
mounts:
- path: /mnt/mergerfs
state: mounted
branches:
- /mnt/data/device0
- /mnt/data/device1
- /mnt/data/device2
options: allow_other,use_ino
- path: /mnt/mergerfs
state: mounted
branches:
- /mnt/data/device0
- /mnt/data/device1
- /mnt/data/device2
options: allow_other,use_ino
devices:
- uuid: a54c1bde-1400-4975-bf24-08c603ca3a11 # /dev/sdc1
path: /mnt/data/device0
- uuid: 727dddaa-f7a1-439a-995f-5f4d35322e08 # /dev/sdd1
path: /mnt/data/device1
- uuid: f3cff115-9adc-4761-b1e9-e81055f3e0af # /dev/sda1
path: /mnt/data/device2
# SSD for downloads / transcoding
- uuid: c528bf82-61ab-4f3d-87e0-d1e6e02ef7ec # /dev/sdf
path: /mnt/ssd0/
- uuid: a54c1bde-1400-4975-bf24-08c603ca3a11 # /dev/sdc1
path: /mnt/data/device0
- uuid: 727dddaa-f7a1-439a-995f-5f4d35322e08 # /dev/sdd1
path: /mnt/data/device1
- uuid: f3cff115-9adc-4761-b1e9-e81055f3e0af # /dev/sda1
path: /mnt/data/device2
# SSD for downloads / transcoding
- uuid: c528bf82-61ab-4f3d-87e0-d1e6e02ef7ec # /dev/sdf
path: /mnt/ssd0/
services:
- name: gitea
endpoint_id: 2
- name: mealie
endpoint_id: 2
- name: linkding
endpoint_id: 2
- name: overseerr
endpoint_id: 2
- name: nextcloud
endpoint_id: 2
- name: dashboards
endpoint_id: 2
- name: nginx-proxy-manager
endpoint_id: 2
- name: plex
endpoint_id: 2
- name: uptime-kuma
endpoint_id: 2
- name: vpn-stack
endpoint_id: 2
#- name: docker-volume-backup
# endpoint_id: 2
- name: mariadb
endpoint_id: 2
- name: photoprism
endpoint_id: 2
- name: olivetin
endpoint_id: 2
- name: gitea
endpoint_id: 2
- name: mealie
endpoint_id: 2
- name: linkding
endpoint_id: 2
- name: overseerr
endpoint_id: 2
- name: nextcloud
endpoint_id: 2
- name: dashboards
endpoint_id: 2
- name: nginx-proxy-manager
endpoint_id: 2
- name: plex
endpoint_id: 2
- name: uptime-kuma
endpoint_id: 2
- name: vpn-stack
endpoint_id: 2
- name: mariadb
endpoint_id: 2
- name: photoprism
endpoint_id: 2
- name: olivetin
endpoint_id: 2
# any additional docker networks that should be created
docker_networks:
- mariadb_net
- mariadb_net
# use portainer
container_deployment_mode: portainer

@ -1,5 +1,6 @@
---
- hosts: qnap
- name: Backup Docker Volumes.
hosts: qnap
become: true
vars:
# corrsponds to which category of backups will be used.
@ -7,32 +8,28 @@
schedule: nightly
pre_tasks:
- name: Include vault variables.
include_vars: '../{{vault_file}}'
tags: [always]
- name: Include vault variables.
ansible.builtin.include_vars: '../{{ vault_file }}'
tags: [always]
tasks:
- name: Find Containers With Backup Label
register: docker_info
docker_host_info:
containers: true
containers_filters:
label:
- "ie.cianhatton.backup.enabled=true"
- "ie.cianhatton.backup.schedule={{ schedule }}"
- "ie.cianhatton.backup.enabled=true"
- "ie.cianhatton.backup.schedule={{ schedule }}"
register: filter_output
- debug: msg="{{filter_output}}"
- name: Get Container Names
set_fact: container_names="{{ filter_output.containers | map(attribute="Names") | flatten }}"
- debug: msg="{{container_names}}"
ansible.builtin.set_fact: container_names="{{ filter_output.containers | map(attribute="Names") | flatten }}"
- name: Backup Containers with backup label
include_role:
name: chatton.docker_backup.docker_s3_backup
ansible.builtin.include_role:
name: chatton.docker_backup.docker_s3_backup
vars:
container_backup: "{{ container_item | regex_replace('^\\/', '') }}"
container_backup: "{{ container_item | regex_replace('^\\/', '') }}"
with_items: "{{ container_names }}"
loop_control:
loop_var: container_item

@ -7,12 +7,13 @@
hosts: localhost
connection: local
tasks:
- name: Generate an OpenSSH rsa keypair for ansible
community.crypto.openssh_keypair:
path: ~/.ssh/ansible
passphrase: ''
- name: Generate an OpenSSH rsa keypair for ansible
community.crypto.openssh_keypair:
path: ~/.ssh/ansible
passphrase: ''
- hosts: all
- name: Bootstrap Ansible hosts.
hosts: all
become: true
roles:
- role: bootstrap
- role: bootstrap

@ -1,9 +1,10 @@
---
- hosts: qnap
- name: Restore a docker volume.
hosts: qnap
become: true
pre_tasks:
- name: Include vault variables.
include_vars: '../{{vault_file}}'
ansible.builtin.include_vars: '../{{ vault_file }}'
tags: [always]
roles:
- role: chatton.docker_backup.docker_s3_volume_restore

@ -4,51 +4,51 @@
hosts: all
become: true
pre_tasks:
- name: Update Packages
apt:
upgrade: dist
update_cache: true
- name: Update Packages
ansible.builtin.apt:
upgrade: dist
update_cache: true
roles:
- role: setup_users
- role: setup_users
- name: Install docker on docker hosts
hosts: dockerhosts
become: true
roles:
- role: setup_docker
tags: [setup, docker]
- role: setup_docker
tags: [setup, docker]
- name: Setup and deploy services on the QNAP
hosts: qnap
become: true
pre_tasks:
- name: Include vault variables.
include_vars: '../{{vault_file}}'
tags: [always]
- name: Include vault variables.
ansible.builtin.include_vars: '../{{ vault_file }}'
tags: [always]
roles:
- role: setup_mergerfs
tags: [mergerfs]
- role: setup_samba
tags: [samba]
- role: setup_portainer
tags: [services, portainer]
- role: setup_hosted_services
tags: [services]
- role: setup_mergerfs
tags: [mergerfs]
- role: setup_samba
tags: [samba]
- role: setup_portainer
tags: [services, portainer]
- role: setup_hosted_services
tags: [services]
- hosts: linodes
- name: Setup home lab on linode instances.
hosts: linodes
become: true
pre_tasks:
- name: Include vault variables.
include_vars: '../{{vault_file}}'
tags: [always]
- name: Include vault variables.
ansible.builtin.include_vars: '../{{ vault_file }}'
tags: [always]
roles:
- role: setup_samba
tags: [samba]
- role: setup_docker
tags: [docker]
- role: setup_hosted_services
tags: [services]
- role: setup_samba
tags: [samba]
- role: setup_docker
tags: [docker]
- role: setup_hosted_services
tags: [services]

@ -1,6 +1,8 @@
- hosts: localhost
---
- name: Setup linode instance.
hosts: localhost
become: true
roles:
- role: roles/setup_linode
vars:
state: present
- role: roles/setup_linode
vars:
state: present

@ -1,48 +1,48 @@
---
- hosts: all
- name: Verify HomeLab has been correctly set up.
hosts: all
become: true
pre_tasks:
- name: Include vault variables.
include_vars: ../{{vault_file}}
tags:
- always
- name: Include vault variables.
ansible.builtin.include_vars: ../{{ vault_file }}
tags:
- always
tasks:
- name: Docker Compose Files Exist
command: stat {{directories.docker_compose_directory}}/{{ item.name }}/docker-compose.yml
with_items: '{{services}}'
changed_when: false
register: docker_compose_stat
- name: Docker Compose Files Exist
ansible.builtin.command: stat {{ directories.docker_compose_directory }}/{{ item.name }}/docker-compose.yml
with_items: '{{ services }}'
changed_when: false
register: docker_compose_stat
- name: Assert all Docker Compose files were created
assert:
that: item.rc == 0
with_items: '{{docker_compose_stat.results}}'
- name: Assert all Docker Compose files were created
ansible.builtin.assert:
that: item.rc == 0
with_items: '{{ docker_compose_stat.results }}'
- name: Populate service facts
service_facts: {}
- name: Assert docker is installed and started
assert:
that:
- ansible_facts.services.docker.state == "running"
- ansible_facts.services['docker.service'].status == "enabled"
- name: Inspect all images
docker_image_info: {}
register: image_details
- name: Assert desired images exist
assert:
that: {{item in image_details.images | map(attribute='RepoTags') | flatten: !!null ''}: !!null ''}
with_items: '{{desired_docker_images}}'
- name: Populate service facts
ansible.builtin.service_facts: {}
- name: Fetch Sudoers Files
command: stat /etc/sudoers.d/{{item.name}}
changed_when: false
register: sudoers_stat
with_items: '{{users}}'
when: item.passwordless_sudo == true
- name: Assert sudoers files are created
assert:
that: item.rc == 0
with_items: '{{sudoers_stat.results}}'
- name: Assert docker is installed and started
ansible.builtin.assert:
that:
- ansible_facts.services.docker.state == "running"
- ansible_facts.services['docker.service'].status == "enabled"
- name: Inspect all images
docker_image_info: {}
register: image_details
- name: Assert desired images exist
ansible.builtin.assert:
that: "{{ item in image_details.images | map(attribute='RepoTags') | flatten }}"
with_items: '{{ desired_docker_images }}'
- name: Fetch Sudoers Files
ansible.builtin.command: stat /etc/sudoers.d/{{ item.name }}
changed_when: false
register: sudoers_stat
with_items: '{{ users }}'
when: item.passwordless_sudo
- name: Assert sudoers files are created
ansible.builtin.assert:
that: item.rc == 0
with_items: '{{ sudoers_stat.results }}'

@ -1,53 +1,12 @@
galaxy_info:
author: Cian Hatton
namespace: chatton
description: your role description
company: your company (optional)
# 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
description: Bootstrap ansible
license: MIT
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
min_ansible_version: "2.1"
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.
platforms:
- name: Debian
versions:
- all
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

@ -1,13 +1,14 @@
---
- name: Update Packages
apt:
ansible.builtin.apt:
upgrade: dist
update_cache: true
- name: Create ansible user
user:
ansible.builtin.user:
name: ansible
groups: root
system: true
shell: /bin/bash
- name: Add ssh key for ansible
authorized_key:
@ -16,7 +17,7 @@
key: "{{ lookup('file', '~/.ssh/ansible.pub') }}"
- name: Add sudoers file for ansible
copy:
ansible.builtin.copy:
src: sudoer_ansible
dest: /etc/sudoers.d/ansible
owner: root

@ -63,10 +63,10 @@
- debug: msg="{{ get_out }}"
- set_fact:
volume_details: "{{ volume_details |default([]) + [ {'mount': item.0, 's3_key': item.1} ] }}"
volume_details: "{{ volume_details | default([]) + [ {'mount': item.0, 's3_key': item.1} ] }}"
with_together:
- "{{ volume_mounts }}"
- "{{ container_s3_keys }}"`
- "{{ container_s3_keys }}"
- debug: msg="{{ volume_details }}"

@ -1,10 +1,12 @@
galaxy_info:
author: Cian Hatton
namespace: chatton
description: Bootstrap ansible
company: your company (optional)
description: Setup Docker
license: MIT
min_ansible_version: 2.1
min_ansible_version: "2.1"
galaxy_tags: []
platforms:
- name: Debian
versions:
- all
dependencies: []

@ -7,46 +7,44 @@
# following official instructions here: https://docs.docker.com/engine/install/debian/
- name: Install packages using apt
apt:
ansible.builtin.apt:
name:
- ca-certificates
- curl
- gnupg2
- lsb-release
- pip
- ca-certificates
- curl
- gnupg2
- lsb-release
- pip
state: present
update_cache: true
- name: Add Docker GPG apt Key
apt_key:
ansible.builtin.apt_key:
url: https://download.docker.com/linux/debian/gpg
state: present
# TODO: paramaterize this
- name: Add Docker Repository
apt_repository:
ansible.builtin.apt_repository:
repo: deb https://download.docker.com/linux/debian buster stable
state: present
- name: Install docker packages using apt
apt:
ansible.builtin.apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
state: present
update_cache: true
- name: Install Docker Module for Python
pip:
name: docker
- name: Install Docker Compose Module for Python
pip:
name: docker-compose
- name: Install Docker Modules for Python
ansible.builtin.pip:
name:
- docker
- docker-compose
- name: Ensure docker is started
service:
ansible.builtin.service:
name: docker
state: started

@ -1,96 +1,96 @@
pageInfo:
title: Home Lab
sections:
- name: Dashboards
widgets:
- type: gl-disk-space
options:
hostname: http://qnap:8083
- type: crypto-watch-list
options:
currency: GBP
sortBy: marketCap
assets:
- bitcoin
- ethereum
- cosmos
- polkadot
- dogecoin
items:
- title: Dash Dot
icon: hl-dashdot
url: http://qnap:3010
- title: Uptime Kuma
icon: hl-uptime-kuma
url: http://qnap:3001
- title: Tautulli
icon: hl-tautulli
url: http://qnap:8182
- title: Glances
icon: hl-glances
url: http://qnap:8083
- name: Media Stack
items:
- title: Plex
icon: hl-plex
url: http://qnap:32400
statusCheck: false
- title: Sonarr
icon: hl-sonarr
url: http://qnap:8989
- title: Radarr
icon: hl-radarr
url: http://qnap:7878
- title: Overseerr
icon: hl-overseerr
url: http://qnap:5055
- title: Jackett
icon: hl-jackett
url: http://qnap:9117
statusCheckUrl: http://qnap:9117/health
- title: Qbittorrent
icon: hl-qbittorrent
url: http://qnap:15000
- name: Tools
items:
- title: Photoprism
description: Manager photos
icon: hl-photoprism
url: http://qnap:2342
- title: Olivetin
description: Run pre-defined shell commands
icon: hl-olivetin
url: http://qnap:1337
- title: Linkding
description: Manager photos
icon: hl-linkding
url: http://qnap:9090
- title: Nextcloud
icon: hl-nextcloud
url: http://qnap:8081
- title: Mealie
icon: hl-mealie
url: https://mealie.cianhatton.ie
- title: Gitea
icon: hl-gitea
url: https://git.cianhatton.ie
- name: System Admin
items:
- title: Portainer
description: Manage docker apps using Portainer
icon: hl-portainer
url: http://qnap:9000
- title: Webmin
icon: hl-webmin
url: http://qnap:10000
- title: Adminer
description: Manage MariaDB
icon: hl-adminer
url: http://qnap:3307
- title: Nginx Proxy Manager
description: Manage reverse proxies
icon: hl-nginx
url: http://qnap:8181
- name: Dashboards
widgets:
- type: gl-disk-space
options:
hostname: http://qnap:8083
- type: crypto-watch-list
options:
currency: GBP
sortBy: marketCap
assets:
- bitcoin
- ethereum
- cosmos
- polkadot
- dogecoin
items:
- title: Dash Dot
icon: hl-dashdot
url: http://qnap:3010
- title: Uptime Kuma
icon: hl-uptime-kuma
url: http://qnap:3001
- title: Tautulli
icon: hl-tautulli
url: http://qnap:8182
- title: Glances
icon: hl-glances
url: http://qnap:8083
- name: Media Stack
items:
- title: Plex
icon: hl-plex
url: http://qnap:32400
statusCheck: false
- title: Sonarr
icon: hl-sonarr
url: http://qnap:8989
- title: Radarr
icon: hl-radarr
url: http://qnap:7878
- title: Overseerr
icon: hl-overseerr
url: http://qnap:5055
- title: Jackett
icon: hl-jackett
url: http://qnap:9117
statusCheckUrl: http://qnap:9117/health
- title: Qbittorrent
icon: hl-qbittorrent
url: http://qnap:15000
- name: Tools
items:
- title: Photoprism
description: Manager photos
icon: hl-photoprism
url: http://qnap:2342
- title: Olivetin
description: Run pre-defined shell commands
icon: hl-olivetin
url: http://qnap:1337
- title: Linkding
description: Manager photos
icon: hl-linkding
url: http://qnap:9090
- title: Nextcloud
icon: hl-nextcloud
url: http://qnap:8081
- title: Mealie
icon: hl-mealie
url: https://mealie.cianhatton.ie
- title: Gitea
icon: hl-gitea
url: https://git.cianhatton.ie
- name: System Admin
items:
- title: Portainer
description: Manage docker apps using Portainer
icon: hl-portainer
url: http://qnap:9000
- title: Webmin
icon: hl-webmin
url: http://qnap:10000
- title: Adminer
description: Manage MariaDB
icon: hl-adminer
url: http://qnap:3307
- title: Nginx Proxy Manager
description: Manage reverse proxies
icon: hl-nginx
url: http://qnap:8181
appConfig:
statusCheck: true
showSplashScreen: false

@ -5,19 +5,19 @@ logLevel: INFO
# Actions (buttons) to show up on the WebUI:
actions:
# Docs: https://docs.olivetin.app/action-container-control.html
- title: Restart Plex
icon: plex
shell: docker restart plex
timeout: 30
- title: Restart Dashy
icon: restart
shell: docker restart dashy
timeout: 30
- title: Restart Dashy 2
icon: restart
shell: docker restart dashy
timeout: 30
- title: Restart Olivetin
icon: restart
shell: docker restart olivetin
timeout: 30
- title: Restart Plex
icon: plex
shell: docker restart plex
timeout: 30
- title: Restart Dashy
icon: restart
shell: docker restart dashy
timeout: 30
- title: Restart Dashy 2
icon: restart
shell: docker restart dashy
timeout: 30
- title: Restart Olivetin
icon: restart
shell: docker restart olivetin
timeout: 30

@ -1,10 +1,9 @@
# handlers file for setup_hosted_services
- name: restart-dashy
command: docker restart dashy
ignore_errors: true
ansible.builtin.command: docker restart dashy
- name: restart-olivetin
command: docker restart olivetin
ansible.builtin.command: docker restart olivetin
- name: restart-docker-volume-backup
command: docker restart docker-volume-backup
ansible.builtin.command: docker restart docker-volume-backup

@ -1,18 +1,12 @@
galaxy_info:
author: Cian Hatton
namespace: chatton
description: your role description
company: your company (optional)
description: Deploy all my hosted services
license: MIT
min_ansible_version: 2.1
min_ansible_version: "2.1"
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.
platforms:
- name: Debian
versions:
- all
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

@ -1,63 +1,71 @@
---
- name: Docker | Pull images
docker_image:
name: '{{item}}'
name: '{{ item }}'
source: pull
with_items:
- ubuntu
- busybox
- ubuntu
- busybox
- name: Docker Compose | Create a directory if it does not exist
file:
path: '{{directories.docker_compose_directory}}/{{item.name}}'
ansible.builtin.file:
path: '{{ directories.docker_compose_directory }}/{{ item.name }}'
state: directory
mode: '0755'
with_items: '{{services}}'
with_items: '{{ services }}'
- name: Docker Compose | Template Docker Compose Files
template:
src: '{{item.name}}.j2'
dest: '{{directories.docker_compose_directory}}/{{item.name}}/docker-compose.yml'
with_items: '{{services}}'
ansible.builtin.template:
src: '{{ item.name }}.j2'
dest: '{{ directories.docker_compose_directory }}/{{ item.name }}/docker-compose.yml'
owner: root
group: root
mode: 0440
with_items: '{{ services }}'
- name: Directories | Ensure required directories
file:
path: '{{item}}'
ansible.builtin.file:
path: '{{ item }}'
state: directory
mode: '0755'
with_items:
- '{{dashy.config_directory}}'
- '{{olivetin.config_directory}}'
- '{{directories.backups_dir}}/.s3tmp'
- '{{ dashy.config_directory }}'
- '{{ olivetin.config_directory }}'
- '{{ directories.backups_dir }}/.s3tmp'
- name: Dashy | Config Files
copy:
src: '{{dashy.source_file}}'
dest: '{{dashy.config_directory}}/{{dashy.config_file}}'
ansible.builtin.copy:
src: '{{ dashy.source_file }}'
dest: '{{ dashy.config_directory }}/{{ dashy.config_file }}'
owner: root
group: root
mode: 0440
notify:
- restart-dashy
- restart-dashy
- name: Olivetin | Config Files
copy:
src: '{{olivetin.source_file}}'
dest: '{{olivetin.config_directory}}/{{olivetin.config_file}}'
ansible.builtin.copy:
src: '{{ olivetin.source_file }}'
dest: '{{ olivetin.config_directory }}/{{ olivetin.config_file }}'
owner: root
group: root
mode: 0440
notify:
- restart-olivetin
- restart-olivetin
- name: Install python dependencies (requests)
pip:
ansible.builtin.pip:
name: requests
- name: Docker | Find docker volumes
shell: docker volume ls -f name={{item.name}} --format '{{ '{{' }} .Name {{ '}}'}}'
with_items: '{{services}}'
ansible.builtin.shell: docker volume ls -f name={{ item.name }} --format '{{ '{{' }} .Name {{ '}}' }}'
with_items: '{{ services }}'
register: find_volumes
changed_when: false
- debug: msg="{{ find_volumes.results | map(attribute='stdout_lines') | list | flatten }}"
- name: Docker | Find volumes that need to be restored
script: scripts/find-volumes-to-restore.py
ansible.builtin.script: scripts/find-volumes-to-restore.py
environment:
EXISTING_VOLUMES: "{{ find_volumes.results | map(attribute='stdout_lines') | list | flatten }}"
SERVICES: '{{ services }}'
@ -67,16 +75,16 @@
register: python_output
changed_when: false
- debug: msg="{{ python_output.stdout_lines | list }}"
- set_fact:
restore_volumes: "{{ restore_volumes | default([]) + [{ 'volume_name': item}] }}"
- name: Build list of volumes to restore.
ansible.builtin.set_fact:
restore_volumes: "{{ restore_volumes | default([]) + [{'volume_name':item}] }}"
with_items: "{{ python_output.stdout_lines | list }}"
- name: Restore any missing volumes from S3
include_role:
ansible.builtin.include_role:
name: chatton.docker_backup.docker_s3_volume_restore
when: restore_volumes is defined
# ignore_errors: true
vars:
docker_backup_restore_force: false
docker_backup_restore_latest_s3_key: true
@ -84,42 +92,58 @@
- name: Docker | Create required docker networks
docker_network:
name: '{{item}}'
name: '{{ item }}'
with_items: '{{ docker_networks }}'
- name: Portainer | Update Stack
when: container_deployment_mode == "portainer"
chatton.portainer.portainer_stack:
username: admin
password: '{{portainer.password}}'
password: '{{ portainer.password }}'
docker_compose_file_path: '{{ directories.docker_compose_directory }}/{{ item.name }}/docker-compose.yml'
stack_name: '{{ item.name }}'
endpoint_id: '{{ item.endpoint_id }}'
state: present
with_items: '{{services}}'
with_items: '{{ services }}'
- name: Docker compose | Update Stack
when: container_deployment_mode == "compose"
docker_compose:
project_src: '{{directories.docker_compose_directory}}/{{ item.name }}'
project_src: '{{ directories.docker_compose_directory }}/{{ item.name }}'
state: present
with_items: '{{services}}'
with_items: '{{ services }}'
- name: Install Ansible pull
tags: ["cron"]
ansible.builtin.pip:
name:
- ansible
# TODO: need to specify ansible pull directly, it doesn't find it when it's in PATH
- name: Ensure Nightly Cron Backups
tags: ["cron"]
ansible.builtin.cron:
name: backup docker volumes (nightly)
weekday: "0"
minute: "0"
hour: "3"
user: ansible
job: "ansible-pull -U https://github.com/chatton/ansible-homelab playbooks/backup-docker-volumes.yml -e schedule=nightly"
weekday: "*"
minute: "*"
hour: "4"
user: "{{ homelab_user }}"
job: >
/home/{{ homelab_user }}/.local/bin/ansible-pull
-U https://github.com/chatton/ansible-homelab playbooks/backup-docker-volumes.yml -e schedule=nightly >> ~/logs/nightly.log 2>&1
cron_file: ansible_nightly_docker_volume_backup
state: present
- name: Ensure Monthly Cron Backups
tags: ["cron"]
ansible.builtin.cron:
name: backup docker volumes (monthly)
month: "*"
day : "1"
user: ansible
job: "ansible-pull -U https://github.com/chatton/ansible-homelab playbooks/backup-docker-volumes.yml -e schedule=monthly"
day: "1"
user: "{{ homelab_user }}"
job: >
/home/{{ homelab_user }}/.local/bin/ansible-pull
-U https://github.com/chatton/ansible-homelab playbooks/backup-docker-volumes.yml -e schedule=monthly >> ~/logs/monthly.log 2>&1
cron_file: ansible_monthly_docker_volume_backup
state: present

@ -1,7 +1,12 @@
$ANSIBLE_VAULT;1.1;AES256 36356161663039666634393933383830653035633438343866643730303434353632383031303965
3465343332353437616663643662343262373333366162300a373662386533363234636234633339 35383439373430656130353938653531636563663066646265643838323230356231333836326262
6439626538643837390a383039373366626637333738386332356361306131323133383534323462 32376564376363663666383639313064316365353037356633363035373632313561643030643933
34663533313231636162306465656433663634643038343938396462643261656238626432633136 39356562353463353034373534386537313634326534623830616362336638396337386631663538
30663236653532316461306636333536373836626537363430613961346137626261333238366234 30633438653936316539326436393634366236616664383835396434373966333166366265636661
39666335653265323565313831303264336331363339333532353939653330383362363965353032 383434386133323961373833303262336439
...
$ANSIBLE_VAULT;1.1;AES256
38343033383061343739363362626366376630376337376639376235316665363736376362633830
6638383135303063363866623262303736393337386364630a353533323537376437343033666334
32353832353466343832643238313834616662333736363738353565623063316438393635343631
6662366132396337320a326335353333306262666561353037356539633432376439666133386463
30326230316634346431346266333030303435313065616665656362663164313638313639313633
63343538653230653330383336386138643636333361326139346336646665366530343537663331
61303639313335343162613838303034616362303935653862666166656634613562376330306165
32373832666438623638616363363931636664633337396336653237356234616438623261353134
62373463313235323233343734363561353237613439663534393537333964323932373837356564
32383536613332323532633534306632373762666236366664383636323264363433396437666437
323637336362613139633237316237666365

@ -1,12 +1,11 @@
# defaults file for setup_linode
ssh_keys:
- "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
label: simple-linode
# hosts that are added to the generated .ini file.
hosts:
- user: root
ip: '{{my_linode.instance.ipv4[0]}}'
linode_hosts:
- user: root
ip: '{{ my_linode.instance.ipv4[0] }}'
# https://www.linode.com/community/questions/17190/obtain-a-list-of-image-and-plan-types-using-linode-apicli
type: g6-standard-2

@ -1,53 +1,13 @@
galaxy_info:
author: Cian Hatton
namespace: chatton
description: your role description
company: your company (optional)
# 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
description: Setup Linode instance
license: MIT
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
min_ansible_version: "2.1"
platforms:
- name: Debian
versions:
- all
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.

@ -1,5 +1,6 @@
---
- name: Include vault variables.
include_vars: defaults/main-vault.yml
ansible.builtin.include_vars: defaults/main-vault.yml
- name: Create a new Linode.
linode_v4:
@ -15,19 +16,22 @@
register: my_linode
- name: Wait for SSH to come up
local_action:
module: wait_for host={{ my_linode.instance.ipv4[0] }} port=22 search_regex=OpenSSH
timeout=320
delegate_to: localhost
ansible.builtin.wait_for:
host: "{{ my_linode.instance.ipv4[0] }}"
port: 22
search_regex: OpenSSH
timeout: 320
- name: Instance Details
debug:
msg: '{{my_linode}}'
ansible.builtin.debug:
msg: '{{ my_linode }}'
- name: Update hosts.ini
blockinfile:
path: hosts.ini
block: |
[linode]
{% for host in hosts %}
{{host.user}}@{{host.ip}}
{% endfor %}
# - name: Update hosts.ini
# blockinfile:
# path: hosts.ini
# block: |
# [linode]
# {% for host in linode_hosts %}
# {{ host.user }}@{{ host.ip }}
# {% endfor %}

@ -1,53 +1,11 @@
galaxy_info:
author: Cian Hatton
namespace: chatton
description: your role description
company: your company (optional)
# 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
description: Configures Mergerfs
license: MIT
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.
min_ansible_version: "2.1"
platforms:
- name: Debian
versions:
- all
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

@ -1,26 +1,22 @@
# dangerous to use this as the device name changes when there are new drives.
# can this be done with an ID?
#- name: Create a ext4 filesystem on /dev/sdb1
# filesystem:
# fstype: ext4
# dev: /dev/sdb1
# state: present
---
- name: Mount Volumes
mount:
path: '{{item.path}}'
src: UUID={{item.uuid}}
ansible.builtin.mount:
path: '{{ item.path }}'
src: UUID={{ item.uuid }}
fstype: ext4
state: mounted
opts: defaults,nofail
loop: '{{ devices }}'
register: volume_out
- debug: msg="{{volume_out}}"
- name: Display volumes.
ansible.builtin.debug:
var: "{{ volume_out }}"
verbosity: 3
# tasks file for setup_mergerfs
- name: Create Mergerfs directory
file:
ansible.builtin.file:
path: /mnt/mergerfs
state: directory
owner: cianhatton
@ -30,11 +26,11 @@
# Ensure the actual folder can't be written to only when it has just been created.
- name: Make /mnt/mergerfs immutable
command: chattr +i /mnt/mergerfs
when: directory_creation.changed == true
ansible.builtin.command: chattr +i /mnt/mergerfs
when: directory_creation.diff.after.path != directory_creation.diff.before.path
- name: Create Mergerfs pool
include_role:
ansible.builtin.include_role:
name: sprat.mergerfs
vars:
mergerfs_mounts: '{{mounts}}'
mergerfs_mounts: '{{ mounts }}'

@ -1,3 +1,4 @@
---
version: '3.2'
services:
portainer:
@ -7,10 +8,10 @@ services:
image: portainer/portainer-ce
container_name: portainer
ports:
- 9000:9000
- 9000:9000
volumes:
- portainer_data:/data
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
- /var/run/docker.sock:/var/run/docker.sock
volumes:
portainer_data:

@ -1,53 +1,15 @@
galaxy_info:
author: Cian Hatton
namespace: chatton
description: your role description
company: your company (optional)
# 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
description: Setup Portainer for my Home Lab
license: MIT
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
min_ansible_version: "2.1"
platforms:
- name: Debian
versions:
- all
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.

@ -1,27 +1,32 @@
- name: Portainer | Create directory if it does not exist
---
- name: Portainer | Create directory if it does not exist.
ansible.builtin.file:
path: '{{directories.docker_compose_directory}}'
path: '{{ directories.docker_compose_directory }}'
state: directory
mode: '0755'
owner: root
group: root
mode: 0440
- name: Portainer | Copy docker compose file
copy:
- name: Portainer | Copy docker compose file.
ansible.builtin.copy:
src: docker-compose.yml
dest: '{{directories.docker_compose_directory}}/docker-compose.yml'
dest: '{{ directories.docker_compose_directory }}/docker-compose.yml'
owner: root
group: root
mode: 0440
- name: Portainer | Check if volume exists
shell: docker volume ls -f name=portainer_portainer_data --format '{{ '{{' }} .Name
{{ '}}' }}'
ansible.builtin.shell: docker volume ls -f name=portainer_portainer_data --format '{{ '{{' }} .Name {{ '}}' }}'
register: portainer_volume
changed_when: false
- name: Portainer | Pull images
docker_image:
name: '{{item}}'
name: '{{ item }}'
source: pull
with_items:
- ubuntu
- busybox
- ubuntu
- busybox
- name: Docker Volume Backup | Restore Portainer volume from S3
when: (portainer_volume.stdout_lines | length) == 0
@ -31,34 +36,17 @@
name: s3-restore-portainer
cleanup: true # delete container after it's done.
state: started # container should execute.
detach: no # task fails if container exits.
detach: false # task fails if container exits.
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /tmp:/tmp # temp s3 archive goes here
- /var/run/docker.sock:/var/run/docker.sock
- /tmp:/tmp # temp s3 archive goes here
env:
AWS_ACCESS_KEY_ID: '{{aws_s3.aws_access_key}}'
AWS_SECRET_ACCESS_KEY: '{{aws_s3.aws_secret_key}}'
AWS_DEFAULT_REGION: '{{aws_s3.region}}'
AWS_BUCKET: '{{aws_s3.bucket}}'
AWS_ENDPOINT: '{{aws_s3.s3_url}}'
AWS_ACCESS_KEY_ID: '{{ aws_s3.aws_access_key }}'
AWS_SECRET_ACCESS_KEY: '{{ aws_s3.aws_secret_key }}'
AWS_DEFAULT_REGION: '{{ aws_s3.region }}'
AWS_BUCKET: '{{ aws_s3.bucket }}'
AWS_ENDPOINT: '{{ aws_s3.s3_url }}'
- name: Portainer | Docker compose up
community.docker.docker_compose:
project_src: '{{directories.docker_compose_directory}}/portainer'
# Don't really need this as long as there is an S3 backup.
#- name: Portainer | Register Admin User
# when: (portainer_volume.stdout_lines | length) == 0
# uri:
# url: http://localhost:9000/api/users/admin/init
# method: POST
# body:
# Username: admin
# Password: "{{portainer.password}}"
# status_code: 200
# body_format: json
# register: result
# until: result.status == 200
# retries: 60
# delay: 1
project_src: '{{ directories.docker_compose_directory }}/portainer'

@ -1,9 +1,10 @@
---
samba_group: smbgroup
samba_user: smbuser
users:
- name: cianhatton
- name: cianhatton
shares:
- /share
- /share/public_files
- /share/private_files
- /share/cian_files
- /share
- /share/public_files
- /share/private_files
- /share/cian_files

@ -1,53 +1,15 @@
galaxy_info:
author: Cian Hatton
namespace: chatton
description: your role description
company: your company (optional)
# 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
description: Setup Samba Shares for my Home Lab.
license: MIT
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
min_ansible_version: "2.1"
platforms:
- name: Debian
versions:
- all
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.

@ -1,53 +1,57 @@
- name: Install samba packages using apt
apt:
---
- name: Install samba packages using apt.
ansible.builtin.apt:
name:
- samba
- samba
state: present
update_cache: true
- name: Ensure samba group exists
- name: Ensure samba group exists.
ansible.builtin.group:
name: '{{samba_group}}'
name: '{{ samba_group }}'
state: present
system: true
notify:
- reload-samba
- reload-samba
- name: Ensure samba user
- name: Ensure samba user.
ansible.builtin.user:
name: '{{samba_user}}'
name: '{{ samba_user }}'
comment: Samba user
group: '{{samba_group}}'
group: '{{ samba_group }}'
shell: /bin/false
create_home: false
notify:
- reload-samba
- reload-samba
- name: Add the User(s) to Samba group
user:
- name: Add the User(s) to Samba group.
ansible.builtin.user:
name: '{{ item.name }}'
groups: '{{ samba_group }}'
append: true
with_items: '{{users}}'
with_items: '{{ users }}'
- name: Ensure Share directories
- name: Ensure Share directories.
ansible.builtin.file:
path: '{{item}}'
path: '{{ item }}'
recurse: true
state: directory
owner: '{{samba_user}}'
group: '{{samba_group}}'
owner: '{{ samba_user }}'
group: '{{ samba_group }}'
mode: u+rw,g+rw
with_items: '{{shares}}'
with_items: '{{ shares }}'
notify:
- reload-samba
- reload-samba
- name: Copy smb conf files
copy:
src: '{{item}}'
dest: /etc/samba/{{item}}
- name: Copy smb conf files.
ansible.builtin.copy:
src: '{{ item }}'
dest: "/etc/samba/{{ item }}"
mode: 0644
owner: "{{ samba_user }}"
group: "{{ samba_group }}"
with_items:
- smb.conf
- shares.conf
- smb.conf
- shares.conf
notify:
- reload-samba
- reload-samba

@ -1,53 +1,15 @@
galaxy_info:
author: Cian Hatton
namespace: chatton
description: your role description
company: your company (optional)
# 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
description: Setup users for my Home Lab
license: MIT
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
min_ansible_version: "2.1"
platforms:
- name: Debian
versions:
- all
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.

@ -1,39 +1,42 @@
# https://stackoverflow.com/questions/37333305/ansible-create-a-user-with-sudo-privileges
- name: Install Sudo
apt:
- name: Install Sudo.
ansible.builtin.apt:
pkg:
- sudo
- sudo
state: latest
update_cache: true
- name: Make sure we have a groups
group:
- name: Make sure we have a groups.
ansible.builtin.group:
name: '{{ item.group }}'
state: present
with_items: '{{ users }}'
- name: Add Users
- name: Add Users.
ansible.builtin.user:
name: '{{ item.name }}'
comment: '{{ item.name }} user'
group: '{{ item.group }}'
with_items: '{{ users }}'
- name: Add sudoers
template:
- name: Add sudoers.
ansible.builtin.template:
src: sudoers.j2
dest: /etc/sudoers.d/{{item.name}}
dest: /etc/sudoers.d/{{ item.name }}
mode: 0440
with_items: '{{ users }}'
when: item.passwordless_sudo == true
when: item.passwordless_sudo
- name: Set authorized key
- name: Set authorized key.
authorized_key:
user: '{{ homelab_user }}'
state: present
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- name: Copy Bashrc
copy:
- name: Copy Bashrc.
ansible.builtin.copy:
src: bash_rc
dest: "/home/{{ homelab_user }}/.bash_rc"
group: "{{ homelab_user }}"
owner: "{{ homelab_user }}"
mode: 0644

Loading…
Cancel
Save