Initial commit - homelab infrastructure
This commit is contained in:
commit
bd7bbf3392
27 changed files with 1234 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
cat > ~/homelab/.gitignore << 'EOF'
|
||||
.env
|
||||
*.tfstate
|
||||
*.tfstate.backup
|
||||
.terraform/
|
||||
11
ansible/ansible.cfg
Normal file
11
ansible/ansible.cfg
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[defaults]
|
||||
inventory = inventory/hosts.yml
|
||||
remote_user = ansible
|
||||
private_key_file = ~/.ssh/homelab
|
||||
host_key_checking = False
|
||||
retry_files_enabled = False
|
||||
|
||||
[privilege_escalation]
|
||||
become = True
|
||||
become_method = sudo
|
||||
become_user = root
|
||||
27
ansible/inventory/group_vars/all/vault.yml
Normal file
27
ansible/inventory/group_vars/all/vault.yml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
$ANSIBLE_VAULT;1.1;AES256
|
||||
64613363653338393162363864326531316465383137313239313439343664303939393164623533
|
||||
6430616230323436323065323164346537373235306166300a646366316163383464376165633538
|
||||
61343362613639343366353962353433323861626239376564663136323262323837333937356636
|
||||
6133633932396336620a613237343731623432336530373334613737343063396339663862663762
|
||||
33626662633865353634643036633333653133666235613737346161663766316465336563306165
|
||||
36633033353132646233383765396266393232346235393033313134376164363736633565623631
|
||||
35653235316562656232393331376136303135636363303832626236663936343939653835316437
|
||||
34393439666365333739386139363861616231323463616666663231353433663164346339343136
|
||||
65333337653330646463373834656131623165653832623738376430623131393838356364313366
|
||||
36623534303966353965383365306265326630363161646231336639663966383233373433633366
|
||||
31623635356234303938663362623232373739373966396230383562303436303736386163336463
|
||||
35383238376637333934363034363134313162646563343666623062366230303466656635353964
|
||||
32303432323666373962656638333838333933353163616330613765666539613932336338353033
|
||||
30363031303134626131333731323334623735386438393930663261616435306664633837653635
|
||||
36663362336231636461363331363033363434623763623131623338363964333638346463623839
|
||||
39666536633936396235323738353731323361656166396134646462626134643530343636386238
|
||||
33623864623437643132383130643962623762626130333536646131313031393333663662393733
|
||||
62643466346330316463393833343931633332613161613963646432613832323963623465633330
|
||||
36666466363130313536613861373665376633323432316337353431663665313762653663666135
|
||||
66623734363836373166643732646338643532343762653937326161313265326364626233373538
|
||||
33383235303531323966633839623763313637326231356165663365336231623564343734626639
|
||||
37313838366237333562643334386631353730386334373539356430313334656339303536323431
|
||||
35636431333932356535386461336138316432313337613463393965633733356164663866666463
|
||||
30313366313531326338323632626363636431643631326139663966613065376163366231613238
|
||||
66373130666461373566396334386534353139313239353163623735636461386162313134393837
|
||||
3733663963653135323065356163316434323465613266643837
|
||||
28
ansible/inventory/hosts.yml
Normal file
28
ansible/inventory/hosts.yml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
all:
|
||||
vars:
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
# User admin a creer sur toutes les VMs
|
||||
admin_user: Elewyn
|
||||
# IP du NAS QNAP pour les montages NFS
|
||||
nas_ip: 192.168.1.208
|
||||
|
||||
children:
|
||||
gateway:
|
||||
hosts:
|
||||
vm-gateway:
|
||||
ansible_host: 192.168.1.254
|
||||
|
||||
forgejo:
|
||||
hosts:
|
||||
vm-forgejo:
|
||||
ansible_host: 192.168.1.50
|
||||
|
||||
nextcloud:
|
||||
hosts:
|
||||
vm-nextcloud:
|
||||
ansible_host: 192.168.1.51
|
||||
|
||||
tools:
|
||||
hosts:
|
||||
vm-tools:
|
||||
ansible_host: 192.168.1.52
|
||||
114
ansible/playbooks/base.yml
Normal file
114
ansible/playbooks/base.yml
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
---
|
||||
# Playbook de base : applique sur TOUTES les VMs
|
||||
# - Mise a jour systeme
|
||||
# - Creation user admin Elewyn
|
||||
# - Hardening SSH
|
||||
# - Installation qemu-guest-agent (integration Proxmox)
|
||||
# - Paquets utilitaires
|
||||
|
||||
- name: Configuration de base des VMs
|
||||
hosts: all
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# -- Mise a jour systeme --
|
||||
- name: Mise a jour des paquets
|
||||
ansible.builtin.dnf:
|
||||
name: "*"
|
||||
state: latest
|
||||
update_cache: true
|
||||
tags: [update]
|
||||
|
||||
# -- Installation paquets de base --
|
||||
- name: Installation des paquets utilitaires
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
- qemu-guest-agent
|
||||
- vim
|
||||
- curl
|
||||
- wget
|
||||
- tar
|
||||
- nfs-utils
|
||||
- bash-completion
|
||||
- python3
|
||||
state: present
|
||||
tags: [packages]
|
||||
|
||||
- name: Activation qemu-guest-agent
|
||||
ansible.builtin.systemd:
|
||||
name: qemu-guest-agent
|
||||
state: started
|
||||
enabled: true
|
||||
tags: [packages]
|
||||
|
||||
# -- Creation utilisateur Elewyn --
|
||||
- name: Creation du groupe {{ admin_user }}
|
||||
ansible.builtin.group:
|
||||
name: "{{ admin_user }}"
|
||||
state: present
|
||||
tags: [users]
|
||||
|
||||
- name: Creation de l'utilisateur {{ admin_user }}
|
||||
ansible.builtin.user:
|
||||
name: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
groups: wheel
|
||||
shell: /bin/bash
|
||||
create_home: true
|
||||
password: "{{ vault_admin_password | password_hash('sha512') }}"
|
||||
state: present
|
||||
tags: [users]
|
||||
|
||||
- name: Cle SSH pour {{ admin_user }}
|
||||
ansible.posix.authorized_key:
|
||||
user: "{{ admin_user }}"
|
||||
key: "{{ lookup('file', '~/.ssh/homelab.pub') }}"
|
||||
state: present
|
||||
tags: [users]
|
||||
|
||||
# wheel peut sudo sans mot de passe (deja par defaut sur Rocky, on s'assure)
|
||||
- name: Sudo sans mot de passe pour wheel
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/sudoers.d/wheel-nopasswd
|
||||
line: "%wheel ALL=(ALL) NOPASSWD: ALL"
|
||||
create: true
|
||||
mode: "0440"
|
||||
validate: "visudo -cf %s"
|
||||
tags: [users]
|
||||
|
||||
# -- Hardening SSH --
|
||||
- name: Desactiver l'authentification par mot de passe SSH
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/ssh/sshd_config
|
||||
regexp: "^#?PasswordAuthentication"
|
||||
line: "PasswordAuthentication no"
|
||||
notify: restart sshd
|
||||
tags: [ssh]
|
||||
|
||||
- name: Desactiver le login root SSH
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/ssh/sshd_config
|
||||
regexp: "^#?PermitRootLogin"
|
||||
line: "PermitRootLogin no"
|
||||
notify: restart sshd
|
||||
tags: [ssh]
|
||||
|
||||
# -- Firewalld --
|
||||
- name: Installation firewalld
|
||||
ansible.builtin.dnf:
|
||||
name: firewalld
|
||||
state: present
|
||||
tags: [firewall]
|
||||
|
||||
- name: Activer firewalld
|
||||
ansible.builtin.systemd:
|
||||
name: firewalld
|
||||
state: started
|
||||
enabled: true
|
||||
tags: [firewall]
|
||||
|
||||
handlers:
|
||||
- name: restart sshd
|
||||
ansible.builtin.systemd:
|
||||
name: sshd
|
||||
state: restarted
|
||||
94
ansible/playbooks/docker.yml
Normal file
94
ansible/playbooks/docker.yml
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
---
|
||||
# Installation Docker + Docker Compose
|
||||
# Cible : forgejo, nextcloud, tools (pas gateway)
|
||||
|
||||
- name: Installation Docker
|
||||
hosts: forgejo:nextcloud:tools
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Installation des prerequis
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
- dnf-utils
|
||||
- device-mapper-persistent-data
|
||||
- lvm2
|
||||
state: present
|
||||
tags: [docker]
|
||||
|
||||
- name: Ajout du repo Docker CE
|
||||
ansible.builtin.yum_repository:
|
||||
name: docker-ce
|
||||
description: Docker CE Stable
|
||||
baseurl: https://download.docker.com/linux/centos/$releasever/$basearch/stable
|
||||
gpgcheck: true
|
||||
gpgkey: https://download.docker.com/linux/centos/gpg
|
||||
enabled: true
|
||||
tags: [docker]
|
||||
|
||||
- name: Installation Docker CE + Compose plugin
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
- containerd.io
|
||||
- docker-compose-plugin
|
||||
state: present
|
||||
tags: [docker]
|
||||
|
||||
- name: Chargement des modules kernel requis par Docker
|
||||
community.general.modprobe:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop:
|
||||
- overlay
|
||||
- br_netfilter
|
||||
tags: [docker]
|
||||
|
||||
- name: Persistance des modules kernel au reboot
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/modules-load.d/docker.conf
|
||||
content: |
|
||||
overlay
|
||||
br_netfilter
|
||||
mode: "0644"
|
||||
tags: [docker]
|
||||
|
||||
- name: Parametres sysctl requis par Docker
|
||||
ansible.posix.sysctl:
|
||||
name: "{{ item.key }}"
|
||||
value: "{{ item.value }}"
|
||||
sysctl_set: true
|
||||
reload: true
|
||||
loop:
|
||||
- { key: "net.bridge.bridge-nf-call-iptables", value: "1" }
|
||||
- { key: "net.bridge.bridge-nf-call-ip6tables", value: "1" }
|
||||
- { key: "net.ipv4.ip_forward", value: "1" }
|
||||
tags: [docker]
|
||||
|
||||
- name: Demarrage containerd
|
||||
ansible.builtin.systemd:
|
||||
name: containerd
|
||||
state: started
|
||||
enabled: true
|
||||
tags: [docker]
|
||||
|
||||
- name: Demarrage et activation Docker
|
||||
ansible.builtin.systemd:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: true
|
||||
tags: [docker]
|
||||
|
||||
- name: Ajout de {{ admin_user }} au groupe docker
|
||||
ansible.builtin.user:
|
||||
name: "{{ admin_user }}"
|
||||
groups: docker
|
||||
append: true
|
||||
tags: [docker]
|
||||
|
||||
handlers:
|
||||
- name: reload firewalld
|
||||
ansible.builtin.systemd:
|
||||
name: firewalld
|
||||
state: reloaded
|
||||
63
ansible/playbooks/forgejo.yml
Normal file
63
ansible/playbooks/forgejo.yml
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
# VM Forgejo : forge logicielle legere
|
||||
# Deploie Forgejo + PostgreSQL via Docker Compose
|
||||
|
||||
- name: Deploiement Forgejo
|
||||
hosts: forgejo
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Creation des repertoires Forgejo
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- /opt/forgejo
|
||||
- /opt/forgejo/data
|
||||
- /opt/forgejo/postgres
|
||||
tags: [forgejo]
|
||||
|
||||
- name: Deploiement docker-compose Forgejo
|
||||
ansible.builtin.copy:
|
||||
src: ../../docker/forgejo/docker-compose.yml
|
||||
dest: /opt/forgejo/docker-compose.yml
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0644"
|
||||
tags: [forgejo]
|
||||
|
||||
- name: Deploiement .env Forgejo
|
||||
ansible.builtin.template:
|
||||
src: forgejo.env.j2
|
||||
dest: /opt/forgejo/.env
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0600"
|
||||
tags: [forgejo]
|
||||
|
||||
- name: Demarrage Forgejo
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: /opt/forgejo
|
||||
state: present
|
||||
tags: [forgejo]
|
||||
|
||||
# Port 3000 (web) + 2222 (SSH Git)
|
||||
- name: Ouverture ports Forgejo
|
||||
ansible.posix.firewalld:
|
||||
port: "{{ item }}"
|
||||
permanent: true
|
||||
state: enabled
|
||||
loop:
|
||||
- 3000/tcp
|
||||
- 2222/tcp
|
||||
notify: reload firewalld
|
||||
tags: [forgejo, firewall]
|
||||
|
||||
handlers:
|
||||
- name: reload firewalld
|
||||
ansible.builtin.systemd:
|
||||
name: firewalld
|
||||
state: reloaded
|
||||
113
ansible/playbooks/gateway.yml
Normal file
113
ansible/playbooks/gateway.yml
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
---
|
||||
# VM Gateway : WireGuard + Caddy
|
||||
# Point d'entree reseau depuis le VPS
|
||||
|
||||
- name: Configuration gateway
|
||||
hosts: gateway
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# -- WireGuard --
|
||||
- name: Installation WireGuard
|
||||
ansible.builtin.dnf:
|
||||
name:
|
||||
- wireguard-tools
|
||||
state: present
|
||||
tags: [wireguard]
|
||||
|
||||
- name: Activation IP forwarding
|
||||
ansible.posix.sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: "1"
|
||||
sysctl_set: true
|
||||
reload: true
|
||||
tags: [wireguard]
|
||||
|
||||
- name: Creation du repertoire WireGuard
|
||||
ansible.builtin.file:
|
||||
path: /etc/wireguard
|
||||
state: directory
|
||||
mode: "0700"
|
||||
tags: [wireguard]
|
||||
|
||||
# La config WireGuard sera a personnaliser avec les cles
|
||||
# generees et l'IP du VPS (phase 5)
|
||||
- name: Deploiement config WireGuard (template)
|
||||
ansible.builtin.template:
|
||||
src: wg0.conf.j2
|
||||
dest: /etc/wireguard/wg0.conf
|
||||
mode: "0600"
|
||||
notify: restart wireguard
|
||||
when: wireguard_configured | default(false)
|
||||
tags: [wireguard]
|
||||
|
||||
# -- Caddy --
|
||||
- name: Installation dnf-plugins-core (requis pour copr)
|
||||
ansible.builtin.dnf:
|
||||
name: dnf-plugins-core
|
||||
state: present
|
||||
tags: [caddy]
|
||||
|
||||
- name: Activation du repo COPR Caddy
|
||||
ansible.builtin.shell: dnf copr enable -y @caddy/caddy
|
||||
args:
|
||||
creates: /etc/yum.repos.d/_copr:copr.fedorainfracloud.org:group_caddy:caddy.repo
|
||||
tags: [caddy]
|
||||
|
||||
- name: Installation Caddy
|
||||
ansible.builtin.dnf:
|
||||
name: caddy
|
||||
state: present
|
||||
tags: [caddy]
|
||||
|
||||
- name: Deploiement Caddyfile
|
||||
ansible.builtin.copy:
|
||||
src: ../../docker/gateway/Caddyfile
|
||||
dest: /etc/caddy/Caddyfile
|
||||
mode: "0644"
|
||||
notify: restart caddy
|
||||
tags: [caddy]
|
||||
|
||||
- name: Activation Caddy
|
||||
ansible.builtin.systemd:
|
||||
name: caddy
|
||||
state: started
|
||||
enabled: true
|
||||
tags: [caddy]
|
||||
|
||||
# -- Firewall --
|
||||
- name: Ouverture ports HTTP/HTTPS
|
||||
ansible.posix.firewalld:
|
||||
service: "{{ item }}"
|
||||
permanent: true
|
||||
state: enabled
|
||||
loop:
|
||||
- http
|
||||
- https
|
||||
notify: reload firewalld
|
||||
tags: [firewall]
|
||||
|
||||
- name: Ouverture port WireGuard
|
||||
ansible.posix.firewalld:
|
||||
port: 51820/udp
|
||||
permanent: true
|
||||
state: enabled
|
||||
notify: reload firewalld
|
||||
tags: [firewall]
|
||||
|
||||
handlers:
|
||||
- name: restart wireguard
|
||||
ansible.builtin.systemd:
|
||||
name: wg-quick@wg0
|
||||
state: restarted
|
||||
enabled: true
|
||||
|
||||
- name: restart caddy
|
||||
ansible.builtin.systemd:
|
||||
name: caddy
|
||||
state: restarted
|
||||
|
||||
- name: reload firewalld
|
||||
ansible.builtin.systemd:
|
||||
name: firewalld
|
||||
state: reloaded
|
||||
97
ansible/playbooks/nextcloud.yml
Normal file
97
ansible/playbooks/nextcloud.yml
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
---
|
||||
# VM Nextcloud : cloud personnel
|
||||
# Deploie Nextcloud + PostgreSQL via Docker Compose
|
||||
# Les donnees utilisateur sont stockees sur le QNAP via NFS
|
||||
|
||||
- name: Deploiement Nextcloud
|
||||
hosts: nextcloud
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# -- Montage NFS vers le QNAP pour les donnees --
|
||||
- name: Creation du repertoire parent /mnt/nas
|
||||
ansible.builtin.file:
|
||||
path: /mnt/nas
|
||||
state: directory
|
||||
mode: "0755"
|
||||
tags: [nfs]
|
||||
|
||||
- name: Creation du point de montage NFS
|
||||
ansible.builtin.shell: mkdir -p /mnt/nas/nextcloud-data
|
||||
args:
|
||||
creates: /mnt/nas/nextcloud-data
|
||||
tags: [nfs]
|
||||
|
||||
- name: Montage NFS QNAP pour les donnees Nextcloud
|
||||
ansible.posix.mount:
|
||||
src: "{{ nas_ip }}:/nextcloud-data"
|
||||
path: /mnt/nas/nextcloud-data
|
||||
fstype: nfs
|
||||
opts: defaults,noatime
|
||||
state: mounted
|
||||
tags: [nfs]
|
||||
|
||||
# -- Deploiement Nextcloud --
|
||||
- name: Creation des repertoires Nextcloud
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- /opt/nextcloud
|
||||
- /opt/nextcloud/postgres
|
||||
tags: [nextcloud]
|
||||
|
||||
- name: Deploiement docker-compose Nextcloud
|
||||
ansible.builtin.copy:
|
||||
src: ../../docker/nextcloud/docker-compose.yml
|
||||
dest: /opt/nextcloud/docker-compose.yml
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0644"
|
||||
tags: [nextcloud]
|
||||
|
||||
- name: Deploiement .env Nextcloud
|
||||
ansible.builtin.template:
|
||||
src: nextcloud.env.j2
|
||||
dest: /opt/nextcloud/.env
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0600"
|
||||
tags: [nextcloud]
|
||||
|
||||
- name: Demarrage Nextcloud
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: /opt/nextcloud
|
||||
state: present
|
||||
tags: [nextcloud]
|
||||
|
||||
- name: Config personnalisee Nextcloud (permissions NFS)
|
||||
ansible.builtin.copy:
|
||||
src: ../../docker/nextcloud/custom.config.php
|
||||
dest: /opt/nextcloud/custom.config.php
|
||||
mode: "0644"
|
||||
tags: [nextcloud]
|
||||
|
||||
- name: Injection config dans le container Nextcloud
|
||||
ansible.builtin.shell: >
|
||||
docker cp /opt/nextcloud/custom.config.php
|
||||
nextcloud:/var/www/html/config/custom.config.php
|
||||
changed_when: false
|
||||
tags: [nextcloud]
|
||||
|
||||
- name: Ouverture port Nextcloud
|
||||
ansible.posix.firewalld:
|
||||
port: 8080/tcp
|
||||
permanent: true
|
||||
state: enabled
|
||||
notify: reload firewalld
|
||||
tags: [nextcloud, firewall]
|
||||
|
||||
handlers:
|
||||
- name: reload firewalld
|
||||
ansible.builtin.systemd:
|
||||
name: firewalld
|
||||
state: reloaded
|
||||
2
ansible/playbooks/templates/forgejo.env.j2
Normal file
2
ansible/playbooks/templates/forgejo.env.j2
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
FORGEJO_DB_PASSWORD={{ vault_forgejo_db_password }}
|
||||
FORGEJO_DOMAIN={{ vault_forgejo_domain }}
|
||||
4
ansible/playbooks/templates/nextcloud.env.j2
Normal file
4
ansible/playbooks/templates/nextcloud.env.j2
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
NEXTCLOUD_DB_PASSWORD={{ vault_nextcloud_db_password }}
|
||||
NEXTCLOUD_ADMIN_USER={{ vault_nextcloud_admin_user }}
|
||||
NEXTCLOUD_ADMIN_PASSWORD={{ vault_nextcloud_admin_password }}
|
||||
NEXTCLOUD_DOMAIN={{ vault_nextcloud_domain }}
|
||||
14
ansible/playbooks/templates/wg0.conf.j2
Normal file
14
ansible/playbooks/templates/wg0.conf.j2
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# WireGuard - A configurer a la phase 5 (VPS)
|
||||
# Generer les cles : wg genkey | tee privatekey | wg pubkey > publickey
|
||||
|
||||
[Interface]
|
||||
Address = 10.0.0.2/24
|
||||
PrivateKey = {{ wireguard_private_key }}
|
||||
ListenPort = 51820
|
||||
|
||||
[Peer]
|
||||
# VPS
|
||||
PublicKey = {{ wireguard_vps_public_key }}
|
||||
Endpoint = {{ wireguard_vps_ip }}:51820
|
||||
AllowedIPs = 10.0.0.1/32
|
||||
PersistentKeepalive = 25
|
||||
46
ansible/playbooks/tools.yml
Normal file
46
ansible/playbooks/tools.yml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
# VM Tools : petits utilitaires
|
||||
# Stirling PDF (convertisseur de fichiers)
|
||||
|
||||
- name: Deploiement outils
|
||||
hosts: tools
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Creation du repertoire tools
|
||||
ansible.builtin.file:
|
||||
path: /opt/tools
|
||||
state: directory
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0755"
|
||||
tags: [tools]
|
||||
|
||||
- name: Deploiement docker-compose tools
|
||||
ansible.builtin.copy:
|
||||
src: ../../docker/tools/docker-compose.yml
|
||||
dest: /opt/tools/docker-compose.yml
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0644"
|
||||
tags: [tools]
|
||||
|
||||
- name: Demarrage des outils
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: /opt/tools
|
||||
state: present
|
||||
tags: [tools]
|
||||
|
||||
- name: Ouverture port Stirling PDF
|
||||
ansible.posix.firewalld:
|
||||
port: 8081/tcp
|
||||
permanent: true
|
||||
state: enabled
|
||||
notify: reload firewalld
|
||||
tags: [tools, firewall]
|
||||
|
||||
handlers:
|
||||
- name: reload firewalld
|
||||
ansible.builtin.systemd:
|
||||
name: firewalld
|
||||
state: reloaded
|
||||
24
ansible/site.yml
Normal file
24
ansible/site.yml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
# Site.yml - Orchestre tous les playbooks dans l'ordre
|
||||
# Usage :
|
||||
# Tout deployer : ansible-playbook site.yml
|
||||
# Une VM seule : ansible-playbook site.yml --limit forgejo
|
||||
# Un role seul : ansible-playbook site.yml --tags docker
|
||||
|
||||
- name: Configuration de base (toutes les VMs)
|
||||
ansible.builtin.import_playbook: playbooks/base.yml
|
||||
|
||||
- name: Installation Docker
|
||||
ansible.builtin.import_playbook: playbooks/docker.yml
|
||||
|
||||
- name: Configuration gateway
|
||||
ansible.builtin.import_playbook: playbooks/gateway.yml
|
||||
|
||||
- name: Deploiement Forgejo
|
||||
ansible.builtin.import_playbook: playbooks/forgejo.yml
|
||||
|
||||
- name: Deploiement Nextcloud
|
||||
ansible.builtin.import_playbook: playbooks/nextcloud.yml
|
||||
|
||||
- name: Deploiement outils
|
||||
ansible.builtin.import_playbook: playbooks/tools.yml
|
||||
3
docker/forgejo/.env.example
Normal file
3
docker/forgejo/.env.example
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Copier en .env et renseigner les valeurs
|
||||
FORGEJO_DB_PASSWORD=change-moi
|
||||
FORGEJO_DOMAIN=forgejo.local
|
||||
43
docker/forgejo/docker-compose.yml
Normal file
43
docker/forgejo/docker-compose.yml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
services:
|
||||
forgejo:
|
||||
image: codeberg.org/forgejo/forgejo:9
|
||||
container_name: forgejo
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
# -- Base de donnees --
|
||||
- FORGEJO__database__DB_TYPE=postgres
|
||||
- FORGEJO__database__HOST=postgres:5432
|
||||
- FORGEJO__database__NAME=forgejo
|
||||
- FORGEJO__database__USER=forgejo
|
||||
- FORGEJO__database__PASSWD=${FORGEJO_DB_PASSWORD}
|
||||
# -- Serveur --
|
||||
- FORGEJO__server__DOMAIN=${FORGEJO_DOMAIN:-forgejo.local}
|
||||
- FORGEJO__server__SSH_DOMAIN=${FORGEJO_DOMAIN:-forgejo.local}
|
||||
- FORGEJO__server__SSH_PORT=2222
|
||||
- FORGEJO__server__ROOT_URL=http://${FORGEJO_DOMAIN:-forgejo.local}:3000/
|
||||
ports:
|
||||
- "3000:3000"
|
||||
- "2222:22"
|
||||
volumes:
|
||||
- ./data:/data
|
||||
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: forgejo-db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- POSTGRES_DB=forgejo
|
||||
- POSTGRES_USER=forgejo
|
||||
- POSTGRES_PASSWORD=${FORGEJO_DB_PASSWORD}
|
||||
volumes:
|
||||
- ./postgres:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U forgejo"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
12
docker/gateway/Caddyfile
Normal file
12
docker/gateway/Caddyfile
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Caddyfile - Reverse proxy interne
|
||||
# A adapter avec ton NDD une fois achete (phase 5)
|
||||
|
||||
# Forgejo
|
||||
:3000 {
|
||||
reverse_proxy 192.168.1.50:3000
|
||||
}
|
||||
|
||||
# Nextcloud
|
||||
:8080 {
|
||||
reverse_proxy 192.168.1.51:8080
|
||||
}
|
||||
5
docker/nextcloud/.env.example
Normal file
5
docker/nextcloud/.env.example
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Copier en .env et renseigner les valeurs
|
||||
NEXTCLOUD_DB_PASSWORD=change-moi
|
||||
NEXTCLOUD_ADMIN_USER=Elewyn
|
||||
NEXTCLOUD_ADMIN_PASSWORD=change-moi
|
||||
NEXTCLOUD_DOMAIN=nextcloud.local
|
||||
4
docker/nextcloud/custom.config.php
Normal file
4
docker/nextcloud/custom.config.php
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
$CONFIG = [
|
||||
'check_data_directory_permissions' => false,
|
||||
];
|
||||
42
docker/nextcloud/docker-compose.yml
Normal file
42
docker/nextcloud/docker-compose.yml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
services:
|
||||
nextcloud:
|
||||
image: nextcloud:30-apache
|
||||
container_name: nextcloud
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
- POSTGRES_HOST=postgres
|
||||
- POSTGRES_DB=nextcloud
|
||||
- POSTGRES_USER=nextcloud
|
||||
- POSTGRES_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
|
||||
- NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER:-admin}
|
||||
- NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
|
||||
- NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_DOMAIN:-nextcloud.local}
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
# Donnees utilisateur sur le QNAP via NFS
|
||||
- /mnt/nas/nextcloud-data:/var/www/html/data
|
||||
# Config locale pour la performance
|
||||
- nextcloud-app:/var/www/html
|
||||
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: nextcloud-db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- POSTGRES_DB=nextcloud
|
||||
- POSTGRES_USER=nextcloud
|
||||
- POSTGRES_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
|
||||
volumes:
|
||||
- ./postgres:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U nextcloud"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
volumes:
|
||||
nextcloud-app:
|
||||
14
docker/tools/docker-compose.yml
Normal file
14
docker/tools/docker-compose.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
services:
|
||||
stirling-pdf:
|
||||
image: frooodle/s-pdf:latest
|
||||
container_name: stirling-pdf
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8081:8080"
|
||||
volumes:
|
||||
- stirling-data:/usr/share/tessdata
|
||||
environment:
|
||||
- DOCKER_ENABLE_SECURITY=false
|
||||
|
||||
volumes:
|
||||
stirling-data:
|
||||
223
homelab.md
Normal file
223
homelab.md
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
# Projet Homelab
|
||||
|
||||
## Infrastructure physique
|
||||
|
||||
### HPE ML110 - Proxmox (192.168.1.242)
|
||||
- **CPU** : 16 x Intel Xeon Silver 4110 @ 2.10GHz (1 Socket)
|
||||
- **RAM** : 32 Go (upgrade en commande : +16 Go HP PC4 1RX4 2666 MHz → 48 Go total)
|
||||
- **CPU upgrade en commande** : Intel Xeon Gold 5120 (14 cores / 28 threads @ 2.20GHz)
|
||||
- **Boot** : EFI
|
||||
- **Kernel** : Linux 6.5.11-8-pve
|
||||
- **Reseau** : vmbr0 (Linux bridge)
|
||||
- **Disques** :
|
||||
- /dev/sda - 2 To
|
||||
- /dev/sda1 - biosboot (1 Mo)
|
||||
- /dev/sda2 - EFI (1 Go)
|
||||
- /dev/sda3 - LVM 31 Go (local + local-lvm)
|
||||
- /dev/sda4 - ext4 104 Go "ISO"
|
||||
- /dev/sda5 - LVM 1.86 To "VMS"
|
||||
|
||||
### QNAP TS-431P2 (192.168.1.208)
|
||||
- **CPU** : Alpine AL-314 (ARM Cortex-A15 quad-core)
|
||||
- **RAM** : 8 Go
|
||||
- **Disques** : 4 baies, RAID 1, disque remplace + RAID reconstruit
|
||||
- **OS** : QTS (on ne touche pas)
|
||||
- **Services actuels** : Plex, bots Discord, NFS/SMB
|
||||
|
||||
### Reseau
|
||||
- Box Orange : 192.168.1.1 (gateway + DNS)
|
||||
- Masque : /24
|
||||
- Pas de VLAN (reseau basique)
|
||||
|
||||
---
|
||||
|
||||
## VMs existantes
|
||||
|
||||
| VM | RAM | vCPU | Disk | Role |
|
||||
|----|-----|------|------|------|
|
||||
| VM-DEDICATED | 20 Go | 8 | 40 Go | Serveurs de jeu |
|
||||
|
||||
---
|
||||
|
||||
## VMs a creer (Terraform - provider bpg/proxmox)
|
||||
|
||||
| VM | VMID | IP | RAM | vCPU | Disk | Role |
|
||||
|----|------|----|-----|------|------|------|
|
||||
| gateway | 200 | 192.168.1.254 | 512 Mo | 1 | 8 Go | WireGuard + Caddy (reverse proxy) |
|
||||
| forgejo | 201 | 192.168.1.50 | 1 Go | 2 | 20 Go | Forge logicielle - http://192.168.1.50:3000 |
|
||||
| nextcloud | 202 | 192.168.1.51 | 4 Go | 3 | 20 Go | Cloud personnel - http://192.168.1.51:8080 |
|
||||
| tools | 203 | 192.168.1.52 | 2 Go | 2 | 10 Go | Stirling PDF - http://192.168.1.52:8081 |
|
||||
| **Total** | | | **5.5 Go** | **7** | **58 Go** | |
|
||||
| **Reste libre** | | | **~4.5 Go** | | | Reserve k3s |
|
||||
|
||||
Template cloud-init : Rocky Linux 9 (VMID 9000)
|
||||
|
||||
---
|
||||
|
||||
## Repartition du stockage
|
||||
|
||||
| Donnee | Emplacement | Raison |
|
||||
|--------|-------------|--------|
|
||||
| OS des VMs + disques virtuels | ML110 (LVM "VMS") | Performance I/O |
|
||||
| BDD PostgreSQL (Forgejo, Nextcloud) | ML110 (local) | BDD sur NFS = lent et risque |
|
||||
| Fichiers Nextcloud (data utilisateur) | QNAP via NFS | Centralise, sauvegardable |
|
||||
| Saves serveurs de jeu | QNAP via NFS | Backups |
|
||||
| Backups VMs (vzdump) | QNAP via NFS | Proxmox backup natif |
|
||||
| Media (Plex) | QNAP (local) | Deja en place |
|
||||
|
||||
---
|
||||
|
||||
## QNAP - Shares NFS a creer
|
||||
|
||||
| Share | Usage | Acces restreint a |
|
||||
|-------|-------|--------------------|
|
||||
| nextcloud-data | Donnees Nextcloud | 192.168.1.51 |
|
||||
| backups | Backups Proxmox | 192.168.1.242 |
|
||||
| game-saves | Saves serveurs de jeu | 192.168.1.x (VM dedicated) |
|
||||
|
||||
---
|
||||
|
||||
## Poste de pilotage
|
||||
|
||||
- **PC Gaming Windows 11** : VSCode + Claude Code, WSL2 Debian
|
||||
- **Laptop Linux Mint** : alternative (non disponible actuellement)
|
||||
- **WSL2 Debian** : Terraform, Ansible, kubectl, Git, cles SSH
|
||||
|
||||
---
|
||||
|
||||
## Architecture reseau cible (avec VPS)
|
||||
|
||||
```
|
||||
Internet --> [VPS Hetzner CX22 ~4 EUR/mois]
|
||||
| Caddy (reverse proxy + TLS Let's Encrypt)
|
||||
| CrowdSec
|
||||
|
|
||||
WireGuard tunnel (10.0.0.0/24)
|
||||
|
|
||||
[VM gateway - 192.168.1.254]
|
||||
|
|
||||
+------+-------+-------+
|
||||
| | | |
|
||||
Forgejo Nextcloud Plex Tools
|
||||
(.50) (.51) (QNAP) (.52)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Stack technique
|
||||
|
||||
| Outil | Usage |
|
||||
|-------|-------|
|
||||
| **Terraform** (bpg/proxmox) | Provisionnement des VMs |
|
||||
| **Ansible** | Configuration des VMs |
|
||||
| **Docker Compose** | Deploiement des services |
|
||||
| **WireGuard** | VPN entre VPS et homelab |
|
||||
| **Caddy** | Reverse proxy + TLS auto |
|
||||
| **Forgejo** | Forge logicielle (syntaxe GitHub Actions) |
|
||||
| **Nextcloud** | Cloud personnel |
|
||||
| **Stirling PDF** | Convertisseur de fichiers |
|
||||
| **k3s** | Kubernetes (phase future) |
|
||||
|
||||
---
|
||||
|
||||
## Arborescence du repo
|
||||
|
||||
```
|
||||
~/homelab/
|
||||
├── .env # Secrets Terraform (jamais commit)
|
||||
├── .gitignore
|
||||
├── terraform/proxmox/
|
||||
│ ├── main.tf # 4 VMs via for_each
|
||||
│ ├── variables.tf
|
||||
│ ├── outputs.tf
|
||||
│ └── terraform.tfvars
|
||||
├── ansible/
|
||||
│ ├── ansible.cfg
|
||||
│ ├── inventory/hosts.yml
|
||||
│ ├── templates/wg0.conf.j2
|
||||
│ ├── site.yml # Orchestre tout
|
||||
│ └── playbooks/
|
||||
│ ├── base.yml # User Elewyn, SSH hardening, packages
|
||||
│ ├── docker.yml # Docker sur forgejo/nextcloud/tools
|
||||
│ ├── gateway.yml # WireGuard + Caddy
|
||||
│ ├── forgejo.yml # Forgejo + PostgreSQL
|
||||
│ ├── nextcloud.yml # Nextcloud + montage NFS QNAP
|
||||
│ └── tools.yml # Stirling PDF
|
||||
└── docker/
|
||||
├── gateway/Caddyfile
|
||||
├── forgejo/
|
||||
│ ├── docker-compose.yml
|
||||
│ └── .env.example
|
||||
├── nextcloud/
|
||||
│ ├── docker-compose.yml
|
||||
│ └── .env.example
|
||||
└── tools/docker-compose.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Users sur les VMs
|
||||
|
||||
| User | Role | Auth |
|
||||
|------|------|------|
|
||||
| ansible | Deploiement Ansible (cloud-init) | Cle SSH homelab |
|
||||
| Elewyn | Admin (sudo via wheel) | Cle SSH homelab |
|
||||
| root | Desactive en SSH | - |
|
||||
|
||||
---
|
||||
|
||||
## Plan d'action
|
||||
|
||||
### Phase 1 - Fondations (FAIT)
|
||||
- [x] WSL2 Debian installe
|
||||
- [x] Terraform, Ansible, Git installes
|
||||
- [x] Cle SSH homelab generee
|
||||
- [x] Template cloud-init Rocky 9 (VMID 9000)
|
||||
- [x] Token API Proxmox (terraform@pam!provider)
|
||||
- [x] Fichiers Terraform + Ansible ecrits
|
||||
|
||||
### Phase 2 - Provisionnement VMs
|
||||
- [x] terraform apply (creer les 4 VMs)
|
||||
- [x] Verifier acces SSH aux VMs (ping + ansible ping OK)
|
||||
|
||||
### Phase 3 - Configuration (Ansible)
|
||||
- [x] base.yml (users, SSH hardening, firewalld, qemu-agent)
|
||||
- [x] Installer collections Ansible (ansible.posix, community.docker, community.general)
|
||||
- [x] Ansible Vault (secrets BDD chiffres)
|
||||
- [x] ansible-playbook site.yml (docker, services)
|
||||
|
||||
### Phase 4 - Services
|
||||
- [x] Forgejo + PostgreSQL deploye
|
||||
- [x] Stirling PDF deploye
|
||||
- [x] Nextcloud + PostgreSQL deploye
|
||||
- [x] NFS QNAP monte (nextcloud-data, backups crees sur QNAP)
|
||||
|
||||
### Phase 5 - Exposition externe
|
||||
- [ ] Acheter NDD (~7 EUR/an)
|
||||
- [ ] Louer VPS Hetzner CX22 (~4 EUR/mois)
|
||||
- [ ] WireGuard VPS <-> gateway
|
||||
- [ ] Caddy reverse proxy + TLS
|
||||
- [ ] DNS Cloudflare
|
||||
|
||||
### Phase 6 - QNAP
|
||||
- [x] Creer shares NFS (nextcloud-data)
|
||||
- [x] Creer share NFS backups
|
||||
- [x] Configurer backups vzdump Proxmox -> NFS (storage qnap-backups, schedule nuit)
|
||||
- [x] Remplacer disque HS + RAID reconstruit
|
||||
|
||||
### Phase 7 - Kubernetes (futur)
|
||||
- [ ] VM k3s single-node (6 Go RAM)
|
||||
- [ ] Migration progressive des services
|
||||
- [ ] ArgoCD (GitOps)
|
||||
- [ ] Monitoring (Grafana/Loki/Prometheus)
|
||||
|
||||
---
|
||||
|
||||
## Budget
|
||||
|
||||
| Poste | Cout |
|
||||
|-------|------|
|
||||
| NDD .fr | ~7 EUR/an |
|
||||
| VPS Hetzner CX22 | ~48 EUR/an |
|
||||
| Disque QNAP remplacement | ~20-30 EUR (une fois) |
|
||||
| **Total premiere annee** | **~80 EUR** |
|
||||
24
terraform/proxmox/.terraform.lock.hcl
Normal file
24
terraform/proxmox/.terraform.lock.hcl
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/bpg/proxmox" {
|
||||
version = "0.99.0"
|
||||
constraints = "~> 0.78"
|
||||
hashes = [
|
||||
"h1:UyNgTFGjDo0Kb9uIM/XrhO0F09eALXyaRqLsFM16XKo=",
|
||||
"zh:2ac2a659c1d9ceb180337ccc2ad86427383420230b2cd298f821cba9cbf5645c",
|
||||
"zh:2f8145d697bd4efbc1ffd3346d686866e104b21303dec3ff2ce0f9f501ddc9be",
|
||||
"zh:2fd459efb1b6658891e290111ca85d906eef42fe27c21af96b95442da8d461de",
|
||||
"zh:3365c9be6501a9018b6b0dd599b48bdef4277f6509b299dde5f25d559d774068",
|
||||
"zh:4088709a948886a22d92f98ba0782481001e9b94a3027cb3a3b39a7ba40be8d2",
|
||||
"zh:537e9c663bc03bc416e615d94c54ebc6a0cb8453029f12344eeefa14fe2a20db",
|
||||
"zh:5871bc9d5d3c3ec7f32b67a63e8127e29e7e92f6c1a9b8d1f98f2f6e9be263ab",
|
||||
"zh:680239bd34a8a1c874a87a48d1062a69338bbd59fddf3c41e605e0fc2a714842",
|
||||
"zh:6fd3445e460361d5ef5d6bf34c731ca7dc84ea7c2e39a2de50546f0f175f089a",
|
||||
"zh:e3d0b208f7b982dc265c7daa77b3cb9ace9789b4ed4ad55107f03a6624be6beb",
|
||||
"zh:e406403644ab5ad85478bfe25db9eeabd28a8c926bf580ba1a0ff37fdf61a05d",
|
||||
"zh:f020a472d78da34c3ebabed07e9019da778e107e215e2e66f4f2e99b033af304",
|
||||
"zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597",
|
||||
"zh:f7afb6b0486c09b2b8e36576e9d64ca36f31940fac574740ecf8ccdee9febb6c",
|
||||
]
|
||||
}
|
||||
122
terraform/proxmox/main.tf
Normal file
122
terraform/proxmox/main.tf
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
# Provider Proxmox (bpg) - plus moderne, pas le bug user list de telmate
|
||||
terraform {
|
||||
required_providers {
|
||||
proxmox = {
|
||||
source = "bpg/proxmox"
|
||||
version = "~> 0.78"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "proxmox" {
|
||||
endpoint = var.proxmox_url
|
||||
api_token = var.proxmox_api_token
|
||||
insecure = true
|
||||
|
||||
ssh {
|
||||
agent = false
|
||||
}
|
||||
}
|
||||
|
||||
# --- Locals : configuration centralisee des VMs ---
|
||||
locals {
|
||||
vms = {
|
||||
gateway = {
|
||||
vmid = 200
|
||||
cores = 1
|
||||
memory = 512
|
||||
balloon = 256
|
||||
disk = 10
|
||||
ip = var.gateway_ip
|
||||
}
|
||||
forgejo = {
|
||||
vmid = 201
|
||||
cores = 2
|
||||
memory = 1024
|
||||
balloon = 512
|
||||
disk = 20
|
||||
ip = var.forgejo_ip
|
||||
}
|
||||
nextcloud = {
|
||||
vmid = 202
|
||||
cores = 3
|
||||
memory = 4096
|
||||
balloon = 2048
|
||||
disk = 20
|
||||
ip = var.nextcloud_ip
|
||||
}
|
||||
tools = {
|
||||
vmid = 203
|
||||
cores = 2
|
||||
memory = 2048
|
||||
balloon = 1024
|
||||
disk = 10
|
||||
ip = var.tools_ip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# --- VMs generees dynamiquement par clonage du template ---
|
||||
resource "proxmox_virtual_environment_vm" "vm" {
|
||||
for_each = local.vms
|
||||
|
||||
name = each.key
|
||||
node_name = var.proxmox_node
|
||||
vm_id = each.value.vmid
|
||||
|
||||
clone {
|
||||
vm_id = var.template_vmid
|
||||
}
|
||||
|
||||
scsi_hardware = "virtio-scsi-single"
|
||||
|
||||
cpu {
|
||||
cores = each.value.cores
|
||||
sockets = 1
|
||||
type = "x86-64-v2-AES"
|
||||
}
|
||||
|
||||
memory {
|
||||
dedicated = each.value.memory
|
||||
floating = each.value.balloon
|
||||
}
|
||||
|
||||
agent {
|
||||
enabled = true
|
||||
timeout = "10s"
|
||||
}
|
||||
|
||||
disk {
|
||||
interface = "scsi0"
|
||||
size = each.value.disk
|
||||
datastore_id = var.storage_name
|
||||
}
|
||||
|
||||
network_device {
|
||||
bridge = var.network_bridge
|
||||
model = "virtio"
|
||||
}
|
||||
|
||||
initialization {
|
||||
ip_config {
|
||||
ipv4 {
|
||||
address = "${each.value.ip}/24"
|
||||
gateway = var.network_gateway
|
||||
}
|
||||
}
|
||||
dns {
|
||||
servers = [var.dns_server]
|
||||
}
|
||||
user_account {
|
||||
username = var.ci_user
|
||||
keys = [var.ssh_public_key]
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
initialization,
|
||||
network_device
|
||||
]
|
||||
}
|
||||
}
|
||||
6
terraform/proxmox/outputs.tf
Normal file
6
terraform/proxmox/outputs.tf
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
output "vm_ips" {
|
||||
description = "IPs des VMs creees"
|
||||
value = {
|
||||
for name, vm in proxmox_virtual_environment_vm.vm : name => local.vms[name].ip
|
||||
}
|
||||
}
|
||||
10
terraform/proxmox/terraform.tfvars
Normal file
10
terraform/proxmox/terraform.tfvars
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
proxmox_node = "SRV-PROXMOX"
|
||||
storage_name = "VMS"
|
||||
network_bridge = "vmbr0"
|
||||
network_gateway = "192.168.1.1"
|
||||
dns_server = "192.168.1.1"
|
||||
gateway_ip = "192.168.1.254"
|
||||
forgejo_ip = "192.168.1.50"
|
||||
nextcloud_ip = "192.168.1.51"
|
||||
tools_ip = "192.168.1.52"
|
||||
|
||||
84
terraform/proxmox/variables.tf
Normal file
84
terraform/proxmox/variables.tf
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
# --- Proxmox ---
|
||||
variable "proxmox_url" {
|
||||
description = "URL de l'API Proxmox (ex: https://192.168.1.242:8006)"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "proxmox_api_token" {
|
||||
description = "Token API au format user@realm!tokenid=secret"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "proxmox_node" {
|
||||
description = "Nom du node Proxmox"
|
||||
type = string
|
||||
default = "SRV-PROXMOX"
|
||||
}
|
||||
|
||||
variable "template_vmid" {
|
||||
description = "VMID du template cloud-init a cloner"
|
||||
type = number
|
||||
default = 9000
|
||||
}
|
||||
|
||||
variable "storage_name" {
|
||||
description = "Nom du stockage pour les disques VM"
|
||||
type = string
|
||||
default = "VMS"
|
||||
}
|
||||
|
||||
# --- Reseau ---
|
||||
variable "network_bridge" {
|
||||
description = "Bridge Proxmox"
|
||||
type = string
|
||||
default = "vmbr0"
|
||||
}
|
||||
|
||||
variable "network_gateway" {
|
||||
description = "Gateway du reseau (box)"
|
||||
type = string
|
||||
default = "192.168.1.1"
|
||||
}
|
||||
|
||||
variable "dns_server" {
|
||||
description = "Serveur DNS"
|
||||
type = string
|
||||
default = "192.168.1.1"
|
||||
}
|
||||
|
||||
variable "gateway_ip" {
|
||||
description = "IP de la VM gateway"
|
||||
type = string
|
||||
default = "192.168.1.254"
|
||||
}
|
||||
|
||||
variable "forgejo_ip" {
|
||||
description = "IP de la VM Forgejo"
|
||||
type = string
|
||||
default = "192.168.1.50"
|
||||
}
|
||||
|
||||
variable "nextcloud_ip" {
|
||||
description = "IP de la VM Nextcloud"
|
||||
type = string
|
||||
default = "192.168.1.51"
|
||||
}
|
||||
|
||||
variable "tools_ip" {
|
||||
description = "IP de la VM tools"
|
||||
type = string
|
||||
default = "192.168.1.52"
|
||||
}
|
||||
|
||||
# --- Cloud-init ---
|
||||
variable "ci_user" {
|
||||
description = "Utilisateur cree par cloud-init"
|
||||
type = string
|
||||
default = "ansible"
|
||||
}
|
||||
|
||||
variable "ssh_public_key" {
|
||||
description = "Cle publique SSH injectee par cloud-init"
|
||||
type = string
|
||||
}
|
||||
Loading…
Reference in a new issue