initial commit

This commit is contained in:
xbazzi 2025-07-07 19:55:34 -06:00
commit 9df999f89f
78 changed files with 974 additions and 0 deletions

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"ansible.python.interpreterPath": "/run/current-system/sw/bin/python",
"ansible.validation.lint.path": "",
"ansible.validation.lint.enabled": false
}

150
README.md Normal file
View File

@ -0,0 +1,150 @@
# Ansible Starter Kit
Easy way for my homies to start up an ansible project for their homelab or local machine.
# Prerequisites
The ideal setup for a homelab is to have:
- The same username/password in all vms/hosts so you don't have to type a different password for each host
- SSH key auth on each host so you don't have to type a password at all
# Ansible basics
I'll explain the basic units of an ansible project. For this example we're going to assume you want to mount
an NFS share in all your hosts.
From bottom to top we have:
## Tasks
A task is the lowest unit in an ansible project.
A task could be:
- Creating a directory
- Installing an os package (curl, docker, nfs-common, etc)
- Starting a docker container
### Examples
```yml
- name: Add SSH key for remote user
ansible.posix.authorized_key:
user: javi
state: present
key: "{{ lookup('file', '/home/javi/.ssh/homelab_keypair_ed25519.pub') }}"
```
```yml
- name: Ensure NFS client is installed
ansible.builtin.package:
name: nfs-common
state: present
become: true
```
## Role
A role is a self contained, re-usable unit that will give a meaningful result. Think of it like a class in a program.
Roles have a list of tasks, as well as variables and files associated with those tasks. All contained in a folder.
A role can look like:
```
roles/
portainer/
├── defaults/
│ └── main.yml # Default variables
├── files/
│ └── ... # Static files to be copied (e.g., configs, scripts)
├── handlers/
│ └── main.yml # Handlers (e.g., service restart)
├── meta/
│ └── main.yml # Role metadata (e.g., dependencies)
├── tasks/
│ └── main.yml # Main list of tasks to execute
├── templates/
│ └── ... # Jinja2 templates
├── vars/
│ └── main.yml # Non-overridable variables
└── README.md # Optional: Document what this role does
sshkey/
├── defaults/
│ └── main.yml # Default variables
├── files/
│ └── ... # Static files to be copied (e.g., configs, scripts)
├── handlers/
│ └── main.yml # Handlers (e.g., service restart)
├── meta/
│ └── main.yml # Role metadata (e.g., dependencies)
├── tasks/
│ └── main.yml # Main list of tasks to execute
├── templates/
│ └── ... # Jinja2 templates
├── vars/
│ └── main.yml # Non-overridable variables
└── README.md # Optional: Document what this role does
```
However, only the `defaults` and `tasks` subfolders and subsequent `main.yml` are required. Everything else is optional.
A role can be:
- Mounting a share
- Deploying a docker container with all its requirements like a database and mapped volumes
# Playbook
A playbook combines roles and task to create a final state in a host or group of hosts.
A playbook can be:
- Make sure all your hosts have sshkey auth, portainer, docker and an nfs share mounted.
- Deploy a suite of apps to a host or multiple hosts
## Example
```yml
---
- name: Deploy apps to apps-1 node
hosts: apps
become: true
roles:
- role: apps/kan
vars:
port: 7070
- role: apps/memos
vars:
port: 7071
- role: apps/vaultwarden
vars:
port: 7072
- role: apps/erugo
vars:
port: 7073
- role: apps/tianji
vars:
port: 7074
- role: apps/stirling-pdf o
vars:
port: 7075
- role: apps/dumbware-todo
vars:
port: 7076
pin: 8989
- role: apps/dumbware-drop
vars:
port: 7077
pin: "8989"
```
# Setup
1. Clone this repo `git clone git@gitgud.foo:javif89/ansible-starter-kit.git [your project name]`
2. Run `setup.sh` to set up the vault password and become password
3. Set up your hosts in `hosts.yml`
4. Start making your roles and playbooks

4
ansible.cfg Executable file
View File

@ -0,0 +1,4 @@
[defaults]
inventory = hosts.yml
roles_path = ./roles
vault_password_file = ~/.ansible-vault-key

47
group_vars/all.yml Executable file
View File

@ -0,0 +1,47 @@
project_root: "{{ inventory_dir }}" # Useful hack for easier file paths
# Postgres
# If you have a main database instance all your
# services will use (which you should), put
# the info here so it's accessible to all
# your playbooks.
pg_host: prod1.lan.xbazzi.com
pg_port: 5432
pg_user: postgres
pg_password: password
docker_dir: /data/docker
# Local paths
docker_stacks: "{{ project_root }}/docker"
assets: "{{ project_root }}/assets"
# Remote paths
remote_stacks: "/home/javi/docker"
remote_app_mounts: "/home/docker"
# Sudo password for your servers
# Sudo password for your servers
ansible_become_pass: !vault |
$ANSIBLE_VAULT;1.1;AES256
64633661313934656164656164623432366339636334653736383330363662313861633338626437
3335386363316431653536373264393537626234306633340a353764396630343664646434636463
65613232303363373237626163306261306266363336336130666331376133653733393864663335
6335663333336139350a346233373231323238376364663761663461383331366264396665383364
6264
# TrueNAS iSCSI stuff
iscsi_target_ip: nas.lan.xbazzi.com # TrueNAS IP
iscsi_target_iqn: iqn.2005-10.org.freenas.ctl:pve-iscsi
# Alma new VM provisioning
hostname: "prod3"
timezone: "America/Denver"
network_config:
interface: "ens18"
address: ""
netmask: "255.255.252.0"
gateway: "10.133.7.103"
dns: ["10.133.7.1"]
nfs_mounts:
- { src: "nas:/mnt/media", path: "/mnt/media", opts: "defaults,nfsvers=4" }

View File

@ -0,0 +1,2 @@
iscsi_target_ip: nas.lan.xbazzi.com # TrueNAS IP
iscsi_target_iqn: iqn.2005-10.org.freenas.ctl:pve-iscsi

6
host_vars/pve1.yml Normal file
View File

@ -0,0 +1,6 @@
vmbr0_ip: 10.69.0.21
vmbr1_1337_ip: 10.133.7.21
vmbr1_666_ip: 10.66.6.21
cluster_iface: "vmbr1.999"
cluster_ip: 10.99.9.1

5
host_vars/pve2.yml Normal file
View File

@ -0,0 +1,5 @@
vmbr0_ip: 10.69.0.22
vmbr1_1337_ip: 10.133.7.22
vmbr1_666_ip: 10.66.6.22
cluster_iface: "vmbr1.999"
cluster_ip: 10.99.9.2

5
host_vars/pve3.yml Normal file
View File

@ -0,0 +1,5 @@
vmbr0_ip: 10.69.0.23
vmbr1_1337_ip: 10.133.7.23
vmbr1_666_ip: 10.66.6.23
cluster_iface: "vmbr1.999"
cluster_ip: 10.99.9.3

28
hosts.yml Executable file
View File

@ -0,0 +1,28 @@
---
all:
children:
pve-nodes:
hosts:
pve1:
ansible_host: pve1
pve2:
ansible_host: pve2
pve3:
ansible_host: pve3
vms:
hosts:
prod1:
ansible_host: prod1
prod2:
ansible_host: prod2
school:
ansible_host: school
new-vm:
ansible_host: 10.133.7.240
# alma-provision:
# hosts:
# new-alma-vm:
# ansible_host: <ip>
# vars:
# ansible_user: root

6
playbooks/backup-pve.yml Normal file
View File

@ -0,0 +1,6 @@
---
- name: Backup /etc/pve from all Proxmox nodes
hosts: pve-nodes
become: yes
roles:
- role: utility/pve_backup

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,6 @@
---
- name: Configure networking for a new node
hosts: pve-nodes
become: true
roles:
- role: pve/setup_networking

View File

@ -0,0 +1,15 @@
---
- name: Deploy DBGate container
hosts: prod1
become: true
roles:
- role: apps/dbgate
vars:
directory: "pg-dev"
container_name: "postgres-dev"
port: 7000
- role: services/postgres
vars:
directory: "pg-beta"
container_name: "postgres-beta"
port: 7001

View File

@ -0,0 +1,16 @@
---
- name: Deploy PostgreSQL container
hosts: prod1
become: true
roles:
- role: services/postgres
- role: services/postgres
vars:
directory: "pg-dev"
container_name: "postgres-dev"
port: 7000
- role: services/postgres
vars:
directory: "pg-beta"
container_name: "postgres-beta"
port: 7001

6
playbooks/example.yml Normal file
View File

@ -0,0 +1,6 @@
---
- name: Example playbook
hosts: vms
become: true
roles:
- role: server/sshkey

View File

@ -0,0 +1,5 @@
- name: Prep all Proxmox nodes for clustering
hosts: pve-nodes
become: yes
roles:
- role: utility/cluster_prep

View File

@ -0,0 +1,8 @@
- name: Provision AlmaLinux 10 VM
hosts: new-vm
become: yes
roles:
- role: provision/alma/common
# - role: provision/alma/network
# - role: provision/alma/nfs
# - role: provision/alma/docker

View File

View File

@ -0,0 +1,20 @@
---
- name: Create app database
ansible.builtin.include_role:
name: postgres/database
vars:
database: "{{ app_name }}"
- name: Create app db user
ansible.builtin.include_role:
name: postgres/user
vars:
user: "{{ app_name }}"
password: "password"
- name: Give app user full priviledges on DB
ansible.builtin.include_role:
name: postgres/priviledges
vars:
database: "{{ app_name }}"
user: "{{ app_name }}"

View File

@ -0,0 +1,4 @@
docker_dir: "/data/docker/dbgate"
port: "6001"
app_port: "3000"
container_name: "postgres"

View File

@ -0,0 +1,19 @@
- name: Create docker folder
ansible.builtin.file:
dest: "{{ docker_dir }}"
state: directory
mode: '0770'
- name: Put up the postgres container
community.docker.docker_container:
name: "{{container_name}}"
image: postgres:17.4
restart_policy: always
state: started
pull: true
ports:
- "{{ port }}:{{ app_port }}"
env:
CONNECTIONS: postgres_con
volumes:
- "dbgate-data:/root/.dbgate"

View File

View File

@ -0,0 +1,45 @@
---
- name: Update apt cache
ansible.builtin.apt:
update_cache: yes
- name: Install prerequisite packages
ansible.builtin.apt:
name:
- ca-certificates
- curl
state: present
- name: Create apt keyrings directory
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
mode: '0755'
- name: Download Docker GPG key
ansible.builtin.get_url:
url: "https://download.docker.com/linux/ubuntu/gpg"
dest: /etc/apt/keyrings/docker.asc
mode: '0644'
- name: Add Docker apt repository
ansible.builtin.apt_repository:
repo: "deb [arch={{ docker_arch }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
filename: docker
state: present
vars:
docker_arch: "{{ ansible_architecture | regex_replace('x86_64', 'amd64') }}"
- name: Update apt cache after adding Docker repository
ansible.builtin.apt:
update_cache: true
- name: Install Docker packages
ansible.builtin.apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
state: present

View File

View File

@ -0,0 +1,22 @@
- name: Pull Portainer Agent image
become: true
community.docker.docker_image:
name: portainer/agent
tag: latest
source: pull
- name: Deploy Portainer Agent container
become: true
community.docker.docker_container:
name: portainer_agent
image: portainer/agent
pull: false # we already pulled above
state: started
restart_policy: always
ports:
- "9001:9001"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
- /:/host
timeout: 120 # wait up to 2m for it to come up

View File

@ -0,0 +1,2 @@
apps: []
stack_name: "willneverexist"

View File

@ -0,0 +1,27 @@
---
- name: Create app mount directories
ansible.builtin.file:
path: "{{ remote_app_mounts }}/{{ item }}"
state: directory
mode: '0777'
loop: "{{ apps }}"
- name: Create stack directory
ansible.builtin.file:
path: "{{ remote_stacks }}/{{ stack_name }}"
state: directory
mode: '0777'
- name: Copy docker-compose.yml to server
ansible.builtin.copy:
src: '{{ docker_stacks }}/{{ stack_name }}/docker-compose.yml'
dest: '{{ remote_stacks }}/{{ stack_name }}/docker-compose.yml'
owner: javi
group: javi
mode: '0777'
- name: Start up the containers
ansible.builtin.command: docker compose up -d
become: true
args:
chdir: "{{ remote_stacks }}/{{ stack_name }}"

View File

View File

@ -0,0 +1,10 @@
---
- name: Create database
delegate_to: localhost
community.postgresql.postgresql_db:
name: "{{ database }}"
state: present
login_host: "{{ pg_host }}"
login_port: "{{ pg_port }}"
login_user: "{{ pg_user }}"
login_password: "{{ pg_password }}"

View File

@ -0,0 +1 @@
priviledges: ALL

View File

@ -0,0 +1,28 @@
---
- name: Grant database-level privileges on "{{ database }}"
delegate_to: localhost
community.postgresql.postgresql_privs:
db: "{{ database }}"
type: database
objs: "{{ database }}"
privs: "CREATE"
role: "{{ user }}"
state: present
login_host: "{{ pg_host }}"
login_port: "{{ pg_port }}"
login_user: "{{ pg_user }}"
login_password: "{{ pg_password }}"
- name: Give user full priviledges on database
delegate_to: localhost
community.postgresql.postgresql_privs:
db: "{{ database }}"
type: schema
objs: public
privs: "{{ priviledges }}"
role: "{{ user }}"
state: present
login_host: "{{ pg_host }}"
login_port: "{{ pg_port }}"
login_user: "{{ pg_user }}"
login_password: "{{ pg_password }}"

View File

@ -0,0 +1 @@
password: "password"

View File

@ -0,0 +1,11 @@
---
- name: Create postgres user
delegate_to: localhost
community.postgresql.postgresql_user:
name: "{{ user }}"
password: "{{ password }}"
state: present
login_host: "{{ pg_host }}"
login_port: "{{ pg_port }}"
login_user: "{{ pg_user }}"
login_password: "{{ pg_password }}"

View File

@ -0,0 +1,26 @@
---
- name: Set system timezone
ansible.builtin.command: timedatectl set-timezone "America/Denver"
register: output
changed_when: output.rc != 0
- name: Set hostname
ansible.builtin.hostname:
name: "{{ hostname }}"
- name: Set repo
ansible.builtin.dnf:
- name: Install baseline packages
ansible.builtin.dnf:
name:
- '@Development tools'
- vim
- curl
- git
- bash-completion
- firewalld
# - fastfetch
# - btop
state: present
update_cache: true

View File

@ -0,0 +1,18 @@
- name: Add Docker repository
ansible.builtin.get_url:
url: https://download.docker.com/linux/centos/docker-ce.repo
dest: /etc/yum.repos.d/docker-ce.repo
- name: Install Docker packages
ansible.builtin.dnf:
name:
- docker-ce
- docker-ce-cli
- containerd.io
state: present
- name: Enable and start Docker
ansible.builtin.service:
name: docker
enabled: yes
state: started

View File

@ -0,0 +1,5 @@
- name: Enable and start firewalld
ansible.builtin.service:
name: firewalld
enabled: yes
state: started

View File

@ -0,0 +1,12 @@
- name: Configure static network
ansible.builtin.template:
src: ifcfg-template.j2
dest: "/etc/sysconfig/network-scripts/ifcfg-{{ network_config.interface }}"
notify: Restart network
- name: Ensure NetworkManager is enabled
ansible.builtin.service:
name: NetworkManager
enabled: true
state: restarted

View File

@ -0,0 +1,6 @@
DEVICE={{ network_config.interface }}
BOOTPROTO=none
ONBOOT=yes
IPADDR={{ network_config.address }}
NETMASK={{ network_config.netmask }}
GATEWAY={{ network_config.gateway }}

View File

@ -0,0 +1,22 @@
- name: Install NFS client
ansible.builtin.dnf:
name: nfs-utils
state: present
- name: Create mount points
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
owner: root
group: root
mode: '0755'
loop: "{{ nfs_mounts }}"
- name: Mount NFS shares
ansible.posix.mount:
src: "{{ item.src }}"
path: "{{ item.path }}"
fstype: nfs
opts: "{{ item.opts }}"
state: mounted
loop: "{{ nfs_mounts }}"

View File

View File

@ -0,0 +1,108 @@
---
# - name: Set hostname
# hostname:
# name: "{{ inventory_hostname }}"
# - name: Disable Proxmox Enterprise repo
# lineinfile:
# path: /etc/apt/sources.list.d/pve-enterprise.list
# regexp: '^deb'
# line: '# deb ...'
# state: present
# ignore_errors: yes # In case the file doesn't exist
- name: Find all sources.list.d files
find:
paths: /etc/apt/sources.list.d
patterns: "*.list"
file_type: file
register: list_files
- name: Comment out any line with 'enterprise' in each file
lineinfile:
path: "{{ item.path }}"
regexp: '^(?!#).*enterprise'
line: '# \g<0>'
backrefs: yes
state: present
loop: "{{ list_files.files }}"
- name: Overwrite sources.list with Proxmox-recommended repos
copy:
dest: /etc/apt/sources.list
content: |
deb http://ftp.debian.org/debian bookworm main contrib
deb http://ftp.debian.org/debian bookworm-updates main contrib
# Proxmox VE pve-no-subscription repository provided by proxmox.com,
# NOT recommended for production use
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription
# security updates
deb http://security.debian.org/debian-security bookworm-security main contrib
mode: '0644'
- name: Add Proxmox no-subscription repo to sources.list.d
copy:
dest: /etc/apt/sources.list.d/pve-no-subscription.list
content: |
deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription
owner: root
group: root
mode: '0644'
- name: Update apt cache
apt:
update_cache: yes
- name: Update /etc/hosts with all PVE nodes
template:
src: hosts.j2
dest: /etc/hosts
mode: "0644"
- name: Ensure search domain and nameserver set properly
template:
src: resolv.j2
dest: /etc/resolv.conf
mode: "0644"
- name: Ensure chrony is installed
apt:
name: chrony
state: present
update_cache: yes
- name: Enable and start chronyd
service:
name: chrony
state: started
enabled: yes
- name: Discover iSCSI targets from TrueNAS
shell: |
iscsiadm -m discovery -t st -p {{ iscsi_target_ip }}
register: iscsi_discovery
changed_when: false
- name: Login to discovered iSCSI target (unauthenticated)
shell: |
iscsiadm -m node -T {{ iscsi_target_iqn }} -p {{ iscsi_target_ip }} --login
register: iscsi_login
changed_when: "'Login to' in iscsi_login.stdout or 'already present' in iscsi_login.stdout"
- name: Make iSCSI login persistent across reboots
shell: |
iscsiadm -m node -T {{ iscsi_target_iqn }} -p {{ iscsi_target_ip }} --op update -n node.startup -v automatic
changed_when: false
# - name: Ensure vg_ha exists
# command: vgs vg_ha
# register: vg_result
# failed_when: vg_result.rc != 0
# changed_when: false
# - name: Debug VG presence
# debug:
# msg: "VG 'vg_ha' found on {{ inventory_hostname }}"

View File

@ -0,0 +1,6 @@
127.0.0.1 localhost
{% for host in groups['pve-nodes'] %}
{{ hostvars[host]['ansible_default_ipv4']['address'] }} {{ host }} {{ host }}.lan.xbazzi.com
{{ hostvars[host]['cluster_ip'] }} {{ host }}-cluster
{% endfor %}

View File

@ -0,0 +1,2 @@
search lan.xbazzi.com
nameserver 10.133.7.1

View File

View File

@ -0,0 +1,26 @@
---
- name: Copy backup script to PVE node
template:
src: backup_pve_config.sh.j2
dest: /home/xbazzi/backup_pve.sh
mode: '0755'
- name: Run backup script
shell: /home/xbazzi/backup_pve.sh
- name: Find most recent backup directory
shell: "ls -td /home/xbazzi/pve_backup_* | head -1"
register: latest_backup_dir
changed_when: false
- name: Archive backup folder
archive:
path: "{{ latest_backup_dir.stdout }}"
dest: "{{ latest_backup_dir.stdout }}.tar.gz"
format: gz
- name: Fetch backup archive to control machine
fetch:
src: "{{ latest_backup_dir.stdout }}.tar.gz"
dest: "backups/{{ inventory_hostname }}.tar.gz"
flat: yes

View File

@ -0,0 +1,23 @@
#!/bin/bash
set -e
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
BACKUP_DIR="/home/xbazzi/pve_backup_${TIMESTAMP}"
NODE_NAME=$(hostname)
echo "🔒 Creating backup directory at $BACKUP_DIR..."
mkdir -p "$BACKUP_DIR"
echo "📁 Backing up /etc/pve..."
cp -a /etc/pve "$BACKUP_DIR/etc_pve"
echo "📄 Saving VM and container config files..."
mkdir -p "$BACKUP_DIR/qemu-server" "$BACKUP_DIR/lxc"
cp -a /etc/pve/qemu-server/*.conf "$BACKUP_DIR/qemu-server/" 2>/dev/null || true
cp -a /etc/pve/lxc/*.conf "$BACKUP_DIR/lxc/" 2>/dev/null || true
echo "💽 Saving storage.cfg..."
cp -a /etc/pve/storage.cfg "$BACKUP_DIR/" 2>/dev/null || true
echo "📦 Backup complete on $NODE_NAME."
echo "🗃️ Location: $BACKUP_DIR"

View File

@ -0,0 +1,5 @@
# - name: Restart networking
# ansible.builtin.systemd:
# name: networking
# state: restarted

View File

@ -0,0 +1,46 @@
---
- name: Set up network interfaces for new PVE node
template:
src: interfaces-xbazzi.j2
# dest: /etc/network/interfaces.d/interfaces-xbazzi
dest: /etc/network/interfaces
owner: root
group: root
mode: "0644"
- name: Apply correct permissions to interfaces.d
file:
path: "/etc/network/interfaces.d"
owner: root
group: root
mode: '0644'
- name: Find all files in the directory
ansible.builtin.find:
paths: /etc/network/interfaces.d/
file_type: file
register: files_to_delete
- name: Delete all files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ files_to_delete.files }}"
- name: Update /etc/hosts with all PVE nodes
template:
src: hosts.j2
dest: /etc/hosts
mode: "0644"
- name: Ensure search domain and nameserver set properly
template:
src: resolv.j2
dest: /etc/resolv.conf
mode: "0644"
- name: Restart networking
ansible.builtin.systemd:
name: networking
state: restarted

View File

@ -0,0 +1,6 @@
127.0.0.1 localhost
{% for host in groups['pve-nodes'] %}
{{ hostvars[host]['ansible_default_ipv4']['address'] }} {{ host }} {{ host }}.lan.xbazzi.com
{{ hostvars[host]['cluster_ip'] }} {{ host }}-cluster
{% endfor %}

View File

@ -0,0 +1,48 @@
auto eno1
iface eno1 inet manual
mtu 1500
auto enp1s0f0
iface enp1s0f0 inet manual
mtu 9000
iface enp1s0f1 inet manual
mtu 9000
# Mgmt interface
auto vmbr0
iface vmbr0 inet static
address {{ vmbr0_ip }}/22
bridge-ports eno1
bridge-stp off
bridge-fd 0
mtu 1500
auto vmbr1
iface vmbr1 inet manual
bridge-ports enp1s0f0
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 2-4094
mtu 9000
# Prod interface
auto vmbr1.1337
iface vmbr1.1337 inet static
address {{ vmbr1_1337_ip }}/22
gateway 10.133.7.1
mtu 9000
# DMZ interface
auto vmbr1.666
iface vmbr1.666 inet static
address {{ vmbr1_666_ip }}/22
mtu 1500
# Cluster network
auto {{ cluster_iface }}
iface {{ cluster_iface }} inet static
address {{ cluster_ip }}/28
mtu 1500

View File

@ -0,0 +1,2 @@
search lan.xbazzi.com
nameserver 10.133.7.1

View File

23
roles/server/ftp/tasks/main.yml Executable file
View File

@ -0,0 +1,23 @@
---
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
- name: Install proftpd package
ansible.builtin.apt:
name: proftpd
state: present
- name: Ensure proftpd is enabled and started
ansible.builtin.service:
name: proftpd
state: started
enabled: true
become: true
- name: Allow FTP through UFW firewall (if UFW is enabled)
community.general.ufw:
rule: allow
port: 21
proto: tcp
ignore_errors: false

View File

View File

@ -0,0 +1,6 @@
---
- name: Add SSH key for remote user
ansible.posix.authorized_key:
user: javi
state: present
key: "{{ lookup('file', '/home/javi/.ssh/homelab_keypair_ed25519.pub') }}"

View File

@ -0,0 +1,5 @@
directory: "postgres"
default_user: "postgres"
default_password: "password"
port: "5432"
container_name: "postgres"

View File

@ -0,0 +1,23 @@
- name: Create data folder
ansible.builtin.file:
dest: "{{ docker_dir }}/{{ directory }}"
state: directory
owner: root
group: docker
mode: '0770'
recurse: yes
- name: Put up the postgres container
community.docker.docker_container:
name: "{{container_name}}"
image: postgres:17.4
restart_policy: always
state: started
pull: true
ports:
- "{{ port }}:5432"
env:
POSTGRES_USER: "{{ default_user }}"
POSTGRES_PASSWORD: "{{ default_password }}"
volumes:
- "{{ docker_dir }}/{{ directory }}/data:/var/lib/postgresql/data/"

View File

@ -0,0 +1,3 @@
mount_host: "{{ hostvars['nas'].ansible_host }}"
share: "/mnt/ALEXANDRIA/"
mount_path: "/mnt/unspecifiedshare"

View File

@ -0,0 +1,21 @@
---
- name: Ensure NFS client is installed
ansible.builtin.package:
name: nfs-common
state: present
become: true
- name: Create mount point directory
ansible.builtin.file:
path: "{{ mount_path }}"
state: directory
mode: '0777'
become: true
- name: Mount share
ansible.posix.mount:
src: "{{ mount_host }}:{{ share }}"
path: "{{ mount_path }}"
fstype: nfs
state: mounted
become: true

28
setup.sh Executable file
View File

@ -0,0 +1,28 @@
echo "**Deleting .git so you can start your own repo"
rm -rf .git
echo "***Ansible vault password***"
echo "This is used to encrypt/descrypt secrets in your vault"
echo "We'll save it to a file in ~/.[file name] so it doesn't have to be typed every time"
echo
read -p "File name (no . prefix): " ansible_vault_pass_filename
read -s -p "Password: " ansible_vault_pass
echo $ansible_vault_pass > ~/.$ansible_vault_pass_filename
echo "vault_password_file = ~/.$ansible_vault_pass_filename" >>ansible.cfg
echo
echo
echo "***Ansible become password***"
echo "A lot of actions need sudo. This password will be stored in group_vars/all.yml encrypted"
read -s -p "Password: " ansible_become_pass
echo "# Sudo password for your servers" >>./group_vars/all.yml
ansible-vault encrypt_string "$ansible_become_pass" --name 'ansible_become_pass' >>./group_vars/all.yml
echo
echo
echo "Setup complete"
echo "You can delete setup.sh since running it again would cause issues"
echo "Config for vault password was output to ./ansible.cfg"
echo "Config for sudo (become) password was output to ./group_vars/all.yml"