Initial commit

This commit is contained in:
Javier Feliz 2025-07-06 12:05:05 -04:00
commit 3e9668bad5
12 changed files with 320 additions and 0 deletions

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
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-test

18
group_vars/all.yml Executable file
View File

@ -0,0 +1,18 @@
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: 10.89.0.102
pg_port: 5432
pg_user: postgres
pg_password: password
# Sudo password for your servers
ansible_become_pass: !vault |
$ANSIBLE_VAULT;1.1;AES256
35613633643566323866643465383731343764616539353330366339616433316565306637363062
6334333432303337643963616435333165303834333237320a636531363761383736356665613164
30616465666565383663626336383764636363303061363731653536313061386333666638326236
6264646466383539370a323961613564616665383435303161306163303038633864653631376665
3263

11
hosts.yml Executable file
View File

@ -0,0 +1,11 @@
---
all:
children:
servers:
hosts:
proxpox_server_1:
ansible_host: 10.89.0.13
vms:
hosts:
vm_1:
ansible_host: 10.89.0.101

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

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,8 @@
# roles/webmin/defaults/main.yml
webmin_repo_url: https://download.webmin.com
webmin_dist: stable
webmin_section: contrib
# Optional HTTP auth
webmin_auth_user: javi
webmin_auth_pass: password

View File

@ -0,0 +1,66 @@
---
- name: Remove any old/malformed Webmin sources list
ansible.builtin.file:
path: /etc/apt/sources.list.d/webmin.list
state: absent
- name: Remove any old Webmin keyring
ansible.builtin.file:
path: /usr/share/keyrings/webmin-archive-keyring.gpg
state: absent
- name: Install Webmin GPG key into its own keyring
ansible.builtin.apt_key:
url: https://download.webmin.com/developers-key.asc
keyring: /usr/share/keyrings/webmin-archive-keyring.gpg
state: present
- name: Add Webmin APT repository
ansible.builtin.apt_repository:
filename: webmin
repo: >-
deb [signed-by=/usr/share/keyrings/webmin-archive-keyring.gpg]
https://download.webmin.com/download/repository
sarge contrib
state: present
- name: Ensure apt prerequisites are installed
ansible.builtin.apt:
name:
- curl
- gnupg
- apt-transport-https
- ca-certificates
state: present
update_cache: true
- name: Configure APT HTTP auth for Webmin
when: webmin_auth_user is defined and webmin_auth_pass is defined
ansible.builtin.copy:
dest: /etc/apt/auth.conf.d/webmin.conf
mode: '0600'
content: |
machine {{ webmin_repo_url | regex_replace('^https?://','') }}
login {{ webmin_auth_user }}
password {{ webmin_auth_pass }}
- name: Remove old Webmin preference file
ansible.builtin.file:
path: /etc/apt/preferences.d/webmin-stable-package-priority
state: absent
- name: Refresh apt cache
ansible.builtin.apt:
update_cache: true
- name: Install Webmin
ansible.builtin.apt:
name:
- webmin
state: present
- name: Ensure Webmin service is enabled & started
ansible.builtin.service:
name: webmin
state: started
enabled: 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"