This is the multi-page printable view of this section.
Click here to print.
Return to the regular view of this page.
Projekty

W tej dokumentacji znajdziesz wszystkie moje pomysły, które są owocem doświadczeń zdobytych podczas realizacji projektów i rozwiązywania problemów technicznych. Każda sekcja jest wynikiem analizy rzeczywistych przypadków, zarówno tych zakończonych sukcesem, jak i tych, które wymagały iteracji i poprawek.
Celem tej dokumentacji jest
-
Usprawnienie procesu pracy – Zawiera gotowe rozwiązania, wzorce oraz dobre praktyki, które można łatwo zaadaptować w przyszłych projektach.
-
Zachowanie wiedzy – Wszystkie kluczowe decyzje projektowe, problemy oraz ich rozwiązania są opisane, aby móc do nich wrócić w razie potrzeby.
-
Inspiracja do ulepszeń – Każda sekcja może stanowić punkt wyjścia do optymalizacji i rozwoju istniejących systemów.
Znajdziesz tu
- Szczegółowe plany funkcji i modułów.
- Przemyślenia na temat architektury i organizacji kodu.
- Notatki dotyczące integracji narzędzi i technologii.
- Wnioski z błędów i najlepsze praktyki ich unikania.
Ta dokumentacja to kompendium wiedzy, które ewoluuje wraz z nowymi wyzwaniami i pomysłami. Zachęcam do jej eksplorowania, aby w pełni wykorzystać potencjał zawartych tutaj wskazówek i spostrzeżeń.
1 - Road Mapa
Rozwój w homelab
Roadmapa rozwoju Homelab stanowi uporządkowany plan ewolucji środowiska, którego celem jest systematyczne podnoszenie jego funkcjonalności, bezpieczeństwa oraz automatyzacji. Pozwala ona jasno określić kierunki zmian, priorytety oraz zależności między kolejnymi etapami. Dzięki temu rozwój infrastruktury staje się przewidywalny, a podejmowane działania – spójne i zgodne z długoterminową wizją całego ekosystemu. Roadmapa obejmuje zarówno modernizację komponentów technicznych, jak i wdrażanie nowych usług, integracji oraz narzędzi wspierających zarządzanie i obserwowalność środowiska.
---
config:
theme: redux
look: neo
---
stateDiagram
direction TB
classDef Sky stroke-width:1px,stroke-dasharray:none,stroke:#374D7C,fill:#E2EBFF,color:#374D7C;
classDef Rose stroke-width:1px,stroke-dasharray:none,stroke:#FF5978,fill:#FFDFE5,color:#8E2236;
classDef Aqua stroke-width:1px,stroke-dasharray:none,stroke:#46EDC8,fill:#DEFFF8,color:#378E7A;
classDef Peach stroke-width:1px,stroke-dasharray:none,stroke:#FBB35A,fill:#FFEFDB,color:#8F632D;
classDef Pine stroke-width:1px,stroke-dasharray:none,stroke:#254336,fill:#27654A,color:#FFFFFF;
[*] --> etap1_1
etap1_1 --> etap2_1
etap1_1 --> etap2_2
etap2_2 --> etap3_1
etap2_2 --> etap3_2
iac_mikrotik --> etap2_1
iac_gitlab --> etap3_1
iac_proxmox --> etap2_2
etap2_2 --> vault
iac_vault --> vault
vault --> haproxy
etap2_2 --> haproxy
etap3_1 --> haproxy
etap2_1 --> etap2_2
etap2_2 --> kubernetes
haproxy --> kubernetes
kubernetes --> [*]
gitlab_ci --> etap3_1
etap1_1:Przygotowanie środowiska developerskiego
etap1_1:- wirtualne masznyny za pomocą vagrant
etap1_1:- kontener deweloperski
etap2_1:Konfiguracja routera za pomocą opentofu
etap2_1:- konfiguracja interfaces
etap2_1:- konfiguracja bridges
etap2_1:- konfiguracja dhcp
etap2_1:- konfiguracja dns
etap2_2:Konfiguracja proxmox
etap2_2:- instalacja proxmox
etap2_2:- utworzenie clustra
etap2_2:- podłączenie strorage NFS
etap3_1:Instalacja gitlab
etap3_1:- Instalacja gitlab-ce (LXC)<br>- Instalacja gitlab runner (LXC)
etap3_2:Utworzenie template vm
etap3_2:- ubuntu 24.04
etap3_2:- alpine 3.x
etap3_2:- alma 11.1
iac_mikrotik:IAC Mikrotik<br>(Opentofu)
iac_gitlab:IAC Gitlab<br>(Opentofu)
iac_proxmox:IAC Proxmox<br>(Opentofu)
vault:Instalacja Vault cluster
vault:- Instalacja Consul<br>- Instalacja Vault<br>- Konfiguracja PKI
iac_vault:IAC Gitlab<br>(Opentofu)
haproxy:Instalacja HA Proxy
haproxy:Konfiguracja LB za pomocą ansible
kubernetes:Stworzenie klastra Kubernetes
kubernetes:Przygotowanie architektury
gitlab_ci:Utworzenie gitlab-ci
l1:Zrealizowane
l2:W trakcie
l3:Do zrobienia
class etap2_1,etap2_2,gitlab_ci,l2 Peach
class etap1_1,etap3_1,etap3_2,iac_mikrotik,iac_gitlab,iac_proxmox,vault,iac_vault,haproxy,l1 Pine
style etap1_1,etap2_1,etap2_2,etap3_1 stroke-width:4px,stroke-dasharray: 0
2 - Infrastruktura

Wstęp do Opentofu
Infrastruktura stanowi fundament środowiska informatycznego w organizacji. Obejmuje wszystkie zasoby – fizyczne i wirtualne – które umożliwiają działanie systemów, usług i aplikacji. W nowoczesnych działach IT infrastruktura musi być automatyzowalna, skalowalna, bezpieczna i możliwa do odtworzenia.
📍
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji. Jednym z najczęściej wykorzystywanych narzędzi do implementacji IaC jest OpenTofu, rozwijany przez firmę HashiCorp. OpenTofu umożliwia automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.
Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.
Architektura projektu OpenTofu w pl.rachuna-net
# Przykładowy opis struktury projektu
pl.rachuna-net/infrastructure/opentofu
├── gitlab-profile # Documentation
├── home.rachuna-net.pl
├── iac-gitlab # IaC - Gitlab Management by terraform
├── modules # Terraform modules
│ ├── gitlab-group # Terraform module for menagment groups
│ ├── gitlab-project # Terraform module for menagment projects
│ ├── proxmox-container
│ ├── proxmox-download-container
│ ├── proxmox-vm
│ ├── routeros-bonding
│ ├── routeros-bridge
│ ├── routeros-dhcp-server
│ ├── routeros-dns
│ ├── routeros-ethernet
│ ├── routeros-system
│ ├── routeros-vlan
│ ├── vault-pki-cert-ca
│ └── vault-pki-cert-intermediate
├── proxmox
├── router.rachuna-net.pl
└── vault
Założenia projektów Infrastructure as a Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym:
- zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
- automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.
Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.
2.1 - Sprzęt (HomeLab)

HomeLab: MikroTik + 3× Proxmox + Synology, opisany jako kod.
📍 Kontekst
Zbudowanie lokalnego HomeLab odwzorowujący małą produkcję (router MikroTik, klaster Proxmox, NAS), utrzymywany jako kod (OpenTofu + Ansible). Celem jest powtarzalność, HA i możliwość szybkiego odtworzenia środowiska pod K8S/CI/CD/observability.
Cel
- Małe, trójwęzłowe środowisko Proxmox + centralny storage Synology + MikroTik jako rdzeń sieci.
- Wzorzec pod IaC: definicje sieci, storage i VM/CT w repo
pl.rachuna-net/infrastructure (moduły iac-mikrotik, iac-proxmox, iac-synology).
- Gotowa baza pod klastry K8S, CI/CD, monitoring/logowanie i eksperymenty z bezpieczeństwem.
Założenia projektowe (IaC)
- Automatyzacja provisioning/upgradow przez OpenTofu/Terraform; konfiguracja systemów i usług przez Ansible.
- Sieć MikroTika (VLAN/bridge/DHCP/firewall) jako kod; testy zmian w CI przed wdrożeniem.
- Wersjonowanie konfiguracji Proxmoxa, eksportów NFS, VIP-ów i adresacji; snapshoty i backupy opisane w repo.
- Odtwarzalność: reinstalacja hostów + import z IaC = identyczne środowisko.
- Router MikroTik – brama WAN/LAN, terminacja VLAN, firewall, DHCP/DNS. Konfiguracja w
iac-mikrotik.
- Klaster Proxmox (3× mini PC) – hypervisor dla VM/LXC, HA, storage współdzielony NFS; hostuje bazowe usługi (Vault/Consul, HAProxy, GitLab Runner, monitoring).
- NAS (Synology) – eksporty NFS dla Proxmoxa i pod przyszłe StorageClass K8S, repo backupów i obrazów VM.
Architektura sieciowa
- Topologia gwiazdy: MikroTik łączy trzy node’y Proxmoxa i NAS; trunk z VLAN-ami do każdego węzła.
- VLAN/bridge: segmenty
mgmt, prod, lab, storage; DHCP per segment, separacja ruchu + reguły firewall.
- Bonding na łączach do NAS (przepustowość + redundancja); VIP-y zarządzane IaC dla usług infrastrukturalnych.
Architektura logiczna
- Proxmox (3×): VM/CT dla GitLab CE + Runners, Vault/Consul, HAProxy/Traefik, monitoring (Prometheus/Grafana/Loki/Promtail), K8S (jeśli uruchomiony).
- NAS: NFS exports (prod/nonprod) dla VM/CT i przyszłych PV w K8S; harmonogram snapshotów i backup offsite.
- MikroTik: routing/NAT, polityki międzysegmentowe, DHCP/DNS, logowanie zdarzeń do centralnego sysloga.
Diagram sprzętu i połączeń
flowchart LR
R[Router MikroTik<br/>WAN + VLAN/Bridge]
subgraph PVE["Klaster Proxmox"]
N1[Node 1<br/>VM/CT]
N2[Node 2<br/>VM/CT]
N3[Node 3<br/>VM/CT]
end
S[NAS<br/>NFS/Backup]
R --> N1
R --> N2
R --> N3
R --> S
S -. shared NFS .- N1
S -. shared NFS .- N2
S -. shared NFS .- N3
Observability, backup, DR
- Monitoring/logi hostów i usług: Prometheus + Loki/Promtail (VM/CT) definiowane jako kod.
- Backup: snapshoty VM/CT w Proxmox, kopie konfiguracji MikroTika, backup eksportów NFS (NAS + offsite).
- DR: reinstalacja Proxmoxa, import konfiguracji z repo IaC, przywrócenie danych z NFS/backupów; procedury opisane w repo.
Podsumowanie
Router MikroTik daje kontrolę nad siecią, klaster 3× Proxmox zapewnia elastyczne zasoby i HA, a Synology spina storage oraz backup. Całość jest wersjonowana i wdrażana jako kod, więc środowisko można szybko odtworzyć i rozbudować o K8S, CI/CD oraz obserwowalność bez utraty spójności.
2.2 - Architektura Sieciowa

Architektura sieciowa
📍 Kontekst
Architektura została zaprojektowana w sposób:
- modularny – każdy segment sieci ma jasno określoną funkcję,
- skalowalny – możliwość dodawania kolejnych VLAN-ów i mostów,
- bezpieczny – separacja ruchu klientów, serwerów, DMZ i storage,
- wysokodostępny – bonding dla infrastruktury storage,
- automatyzowalny – pełna konfiguracja utrzymywana jako kod.
---
config:
theme: neo
layout: dagre
---
flowchart LR
subgraph ETH["Ethernet LAN"]
ETH2["ether 2<br>(LAN-01)"]
ETH3["ether 3<br>(LAN-02)"]
ETH4["ether 4<br>(LAN-03)"]
ETH9["ether 9<br>(LAN-08)"]
ETH10["ether 10<br>(LAN-09)"]
end
subgraph VLAN2["VLAN"]
VLAN2D["VLAN 10<br>(LAN-01)"]
VLAN2I["VLAN 20 - DMZ<br>(LAN-01)"]
end
subgraph VLAN3["VLAN"]
VLAN3D["VLAN 10<br>(LAN-02)"]
VLAN3I["VLAN 20 - DMZ<br>(LAN-02)"]
end
subgraph VLAN4["VLAN"]
VLAN4D["VLAN 10<br>(LAN-03)"]
VLAN4I["VLAN 20 - DMZ<br>(LAN-03)"]
end
subgraph BRIDGE["BRIDGES"]
BRIDGESTORAGE["BRIDGE-STORAGE"]
BRIDGE2["BRIDGE-PROXMOX"]
BRIDGE3["BRIDGE-VMS-DMZ"]
BRIDGE4["BRIDGE-VMS-INTERNAL"]
BRIDGE5["BRIDGE-CLIENTS"]
end
subgraph DHCP["DHCP SERVERS"]
DHCPSTORAGE["BRIDGE-STORAGE"]
DHCP2["BRIDGE-PROXMOX"]
DHCP3["DHCP-VMS-DMZ"]
DHCP4["DHCP-VMS-INTERNAL"]
DHCP5@{ label: "<span style=\"color:\">DHCP-CLIENTS</span>" }
end
subgraph LB["Router"]
ROU0[("router.rachuna-net.pl")]
ETH1["ether 1<br>WAN"]
ROUB1["BONDING-STORAGE"]
ETH
VLAN2
VLAN3
VLAN4
BRIDGE
DHCP
end
subgraph PROXMOX["PROXMOX CLUSTER"]
PVE-S1["PVE-S3"]
PVE-S2["PVE-S2"]
PVE-S3["PVE-S1"]
end
WAN["WAN"] ==> ETH1
ETH1 ==> ROU0
DHCPSTORAGE ==> BRIDGESTORAGE
BRIDGESTORAGE ==> ROUB1
ETH2 ==> PVE-S1
ETH3 ==> PVE-S2
ETH4 ==> PVE-S3
VLAN2D ==> ETH2
VLAN3D ==> ETH3
VLAN4D ==> ETH4
VLAN2I ==> ETH2
VLAN3I ==> ETH3
VLAN4I ==> ETH4
DHCP2 ==> BRIDGE2
BRIDGE2 ==> ETH2 & ETH3 & ETH4
BRIDGE3 ==> VLAN4I & VLAN2I & VLAN3I
BRIDGE4 ==> VLAN2D & VLAN3D & VLAN4D
DHCP3 ==> BRIDGE3
DHCP4 ==> BRIDGE4
DHCP5 ==> BRIDGE5
ROUB1 ==> ETH9 & ETH10
ETH9 ==> STORAGE["storage.rachuna-net.pl"]
ETH10 ==> STORAGE
DHCP5@{ shape: rect}
ROUB1@{ shape: rect}
style ETH fill:#C8E6C9, color: #000000
style BRIDGE fill:#E1BEE7, color: #000000
style DHCP fill:#FFCDD2, color: #000000
click ETH2 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/ethernet/ether2.tf?ref_type=heads"
click ETH3 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/ethernet/ether3.tf?ref_type=heads"
click ETH4 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/ethernet/ether4.tf?ref_type=heads"
click ETH9 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/ethernet/ether9.tf?ref_type=heads"
click ETH10 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/ethernet/ether10.tf?ref_type=heads"
click VLAN2D "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/vlan/ether2-vlan-vms-internal.tf?ref_type=heads"
click VLAN2I "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/vlan/ether2-vlan-vms-dmz.tf?ref_type=heads"
click VLAN3D "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/vlan/ether3-vlan-vms-internal.tf?ref_type=heads"
click VLAN3I "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/vlan/ether3-vlan-vms-dmz.tf?ref_type=heads"
click VLAN4D "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/vlan/ether4-vlan-vms-internal.tf?ref_type=heads"
click VLAN4I "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/vlan/ether4-vlan-vms-dmz.tf?ref_type=heads"
click BRIDGESTORAGE "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/bridge/bridge-storage.tf?ref_type=heads"
click BRIDGE2 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/bridge/bridge-proxmox.tf?ref_type=heads"
click BRIDGE3 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/bridge/bridge-vms-dmz.tf?ref_type=heads"
click BRIDGE4 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/bridge/bridge-vms-internal.tf?ref_type=heads"
click BRIDGE5 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/bridge/bridge-clients.tf?ref_type=heads"
click DHCPSTORAGE "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/dhcp-servers/dhcp-storage.tf"
click DHCP2 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/dhcp-servers/dhcp-proxmox.tf"
click DHCP3 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/dhcp-servers/dhcp-vms-dmz.tf"
click DHCP4 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/dhcp-servers/dhcp-vms-internal.tf"
click DHCP5 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/dhcp-servers/dhcp-clients.tf"
click ETH1 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/ethernet/ether1.tf?ref_type=heads"
click ROUB1 "https://gitlab.rachuna-net.pl/pl.rachuna-net/infrastructure/opentofu/iac-mikrotik/-/blob/main/router.rachuna-net.pl/interfaces/bonding/bonding-storage.tf?ref_type=heads"
linkStyle 7 stroke:#D50000,fill:none
linkStyle 8 stroke:#D50000,fill:none
linkStyle 9 stroke:#D50000,fill:none
linkStyle 10 stroke:#2962FF,fill:none
linkStyle 11 stroke:#2962FF,fill:none
linkStyle 12 stroke:#2962FF
linkStyle 17 stroke:#2962FF,fill:none
linkStyle 18 stroke:#2962FF,fill:none
linkStyle 19 stroke:#2962FF,fill:none
linkStyle 20 stroke:#D50000,fill:none
linkStyle 21 stroke:#D50000,fill:none
linkStyle 22 stroke:#D50000,fill:none
linkStyle 23 stroke:#2962FF,fill:none
linkStyle 24 stroke:#D50000,fill:none
1. Węzeł centralny – router brzegowy
Centralnym elementem architektury jest router router.rachuna-net.pl, który pełni funkcję:
- bramy wyjściowej do Internetu (WAN),
- głównego punktu dystrybucyjnego sieci LAN,
- terminatora VLAN,
- koncentratora mostów (bridge),
- serwera DHCP dla wydzielonych segmentów sieci.
Interfejs ether1 pracuje jako port WAN i zapewnia bezpośredni dostęp do sieci Internet. Pozostałe interfejsy Ethernet są wykorzystywane jako porty dostępowe (LAN) dla serwerów, urządzeń końcowych oraz infrastruktury pomocniczej.
2. Segmentacja sieci i VLAN
Architektura oparta jest na logicznym podziale sieci przy użyciu VLAN-ów i mostów (bridge), co umożliwia separację ruchu oraz kontrolę bezpieczeństwa.
Na portach ether2, ether3 oraz ether4 skonfigurowano następujące sieci logiczne:
- VLAN 20 – VMS-DMZ
- VLAN 10 – VMS-INTERNAL
Porty te są fizycznie podłączone do węzłów wirtualizacyjnych:
pve-s3 – ether2 i ether3
pve-s2 – ether4
Ruch z tych interfejsów trafia do wspólnego węzła logicznego, który rozdziela go do trzech mostów:
- BRIDGE-VMS-DMZ – dla maszyn wystawionych do strefy DMZ
- BRIDGE-VMS-INTERNAL – dla maszyn wewnętrznych
- BRIDGE-PROXMOX – sieć zarządzająca hypervisorami
Każdy z powyższych mostów posiada dedykowany serwer DHCP.
3. Sieć storage – agregacja łączy (bonding)
Bonding kart sieciowych został zastosowany w celu zwiększenia niezawodności oraz wydajności komunikacji z infrastrukturą storage, która stanowi krytyczny element całego środowiska.
Sieć storage jest całkowicie odseparowana logicznie od pozostałych segmentów (VMS, DMZ, CLIENTS), co minimalizuje ryzyko kolizji ruchu oraz wpływu obciążeń użytkowych na operacje magazynowania danych.
Most BRIDGE-STORAGE posiada dedykowany serwer DHCP, a ruch w tej sieci jest ograniczony wyłącznie do komunikacji pomiędzy węzłami klastra a systemem storage.
4. Sieć klientów (BRIDGE-CLIENTS)
Porty:
- ether5 – router domowy
- ether6 – drukarka
- ether7 –
nbo-002-mr
- ether8 –
nbo-001-mr
są podłączone do wspólnego mostu:
Most ten odpowiada za obsługę urządzeń końcowych i posiada oddzielny serwer DHCP dla klientów. Dodatkowo na ether5 zestawiony jest VLAN dedykowany dla ruchu klienckiego.
5. Sieć storage – agregacja łączy
Interfejsy:
zostały połączone logicznie w interfejs:
Agregacja zapewnia:
- większą przepustowość,
- redundancję połączeń.
Interfejs bondingowy prowadzi do serwera storage, który następnie podłączony jest do:
Most ten posiada dedykowany serwer DHCP dla sieci storage.
6. Warstwa serwerów DHCP
W architekturze funkcjonuje pięć niezależnych serwerów DHCP:
| Segment |
Most |
Funkcja |
| VMS-DMZ |
BRIDGE-VMS-DMZ |
Adresacja maszyn w strefie DMZ |
| PROXMOX |
BRIDGE-PROXMOX |
Adresacja hypervisorów |
| VMS-INTERNAL |
BRIDGE-VMS-INTERNAL |
Adresacja maszyn wewnętrznych |
| CLIENTS |
BRIDGE-CLIENTS |
Adresacja urządzeń użytkowników |
| STORAGE |
BRIDGE-STORAGE |
Adresacja systemów magazynu danych |
Taki podział gwarantuje pełną separację domen rozgłoszeniowych (broadcast) oraz umożliwia stosowanie niezależnych polityk bezpieczeństwa.
7. Dostęp do Internetu
Ruch wychodzący ze wszystkich mostów jest routowany przez:
Router pełni rolę centralnej bramy NAT oraz punktu kontroli bezpieczeństwa dla całej infrastruktury.
8. Zarządzanie konfiguracją (IaC)
Cała konfiguracja interfejsów, VLAN-ów, bondingów, mostów oraz serwerów DHCP zarządzana jest w modelu Infrastructure as Code przy użyciu OpenTofu/Terraform.
Każdy element topologii posiada odpowiadający mu plik konfiguracyjny, m.in.:
- interfejsy Ethernet,
- VLAN,
- bonding,
- bridge,
- serwery DHCP.
Umożliwia to:
- pełną wersjonowalność konfiguracji,
- automatyczne odtwarzanie środowiska,
- spójność konfiguracyjną między środowiskami.
2.3 - Vault
Architektura wysokiej dostępności HashiCorp Vault z backendem Consul na Proxmox (LXC)
📍 Kontekst
Celem architektury jest zapewnienie wysokiej dostępności (HA), spójności danych oraz bezpiecznego, kontrolowanego dostępu do usług:
- HashiCorp Vault – centralny system zarządzania sekretami, certyfikatami i tożsamościami,
- HashiCorp Consul – backend storage i mechanizm koordynacji dla Vault,
uruchomionych jako kontenery LXC na platformie Proxmox, z redundantną warstwą dostępową opartą o VIP i HAProxy.
flowchart LR
subgraph External["External"]
U["Users"]
end
subgraph LB["HA Layer"]
VIP[("VIP")]
HA1["HAProxy 1"]
HA2["HAProxy 2"]
HA3["HAProxy 3"]
end
subgraph CONSUL["Consul"]
C1["consul<br>ct01005"]
C2["consul<br>ct01006"]
M4["consul<br>ct01007"]
end
subgraph VAULT["VAULT"]
v1["vault<br>ct01005"]
v2["vault<br>ct01006"]
v3["vault<br>ct01007"]
end
subgraph PROXMOX["Proxmox"]
direction TB
CONSUL
VAULT
end
U == "consul.rachuna-net.pl" ==> VIP
VIP --> HA1 & HA2 & HA3
HA1 == :8200 ==> VAULT
HA2 == :8200 ==> VAULT
HA3 == :8200 ==> VAULT
HA1 == :8501 ==> CONSUL
HA2 == :8501 ==> CONSUL
HA3 == :8501 ==> CONSUL
v1 == :8501 ==> C1
v2 == :8501 ==> C2
v3 == :8501 ==> M4
U == "vault.rachuna-net.pl" ==> VIP
C2@{ shape: rect}
style CONSUL fill:#FFF9C4,color:#000000
style VAULT fill:#C8E6C9,color:#000000
linkStyle 0 stroke:#2962FF
linkStyle 4 stroke:#AA00FF,fill:none
linkStyle 5 stroke:#AA00FF,fill:none
linkStyle 6 stroke:#AA00FF,fill:none
linkStyle 7 stroke:#2962FF,fill:none
linkStyle 8 stroke:#2962FF,fill:none
linkStyle 9 stroke:#2962FF,fill:none
linkStyle 10 stroke:#2962FF,fill:none
linkStyle 11 stroke:#2962FF,fill:none
linkStyle 12 stroke:#2962FF,fill:none
linkStyle 13 stroke:#AA00FF,fill:none
1. Architektura logiczna
Architektura systemu składa się z czterech warstw:
- Warstwa kliencka (External)
- Warstwa wysokiej dostępności (HA Layer)
- Warstwa wirtualizacji (Proxmox)
- Warstwa aplikacyjna (Vault i Consul w LXC)
2. Warstwa kliencka (External)
2.1. Opis
Warstwa kliencka obejmuje:
- administratorów infrastruktury,
- aplikacje wewnętrzne i zewnętrzne,
- systemy CI/CD oraz automaty infrastrukturalne.
Klienci komunikują się wyłącznie z warstwą HA poprzez nazwy DNS.
2.2. Punkty dostępu
| Usługa |
DNS |
Port |
| Vault |
vault.rachuna-net.pl |
443 (https) |
| Consul |
consul.rachuna-net.pl |
443 (https) |
3. Warstwa HA (VIP + HAProxy)
3.1. VIP (Virtual IP)
VIP stanowi pojedynczy, logiczny punkt wejścia do systemu:
- przypisany do nazwy DNS,
- zarządzany mechanizmem typu VRRP (np. keepalived),
- niezależny od fizycznej instancji HAProxy.
📍
VIP zapewnia ciągłość dostępu w przypadku awarii pojedynczego węzła HAProxy.
3.2. HAProxy
Warstwa HA składa się z trzech instancji HAProxy:
- HAProxy 1
- HAProxy 2
- HAProxy 3
Każda instancja jest równorzędna i bezstanowa.
Odpowiedzialności HAProxy:
- rozdzielanie ruchu (load-balancing),
- health-check backendów,
- separacja ruchu Vault i Consul po portach,
- opcjonalna terminacja TLS.
Mapowanie portów:
| Port |
Backend |
Opis |
| 8200 |
Vault |
API oraz UI Vault |
| 8501 |
Consul |
HTTPS API oraz UI Consul |
4. Warstwa wirtualizacji – Proxmox
4.1. Charakterystyka
Platforma Proxmox VE pełni rolę warstwy infrastrukturalnej:
- hostuje kontenery LXC,
- zapewnia izolację procesów,
- umożliwia backup, snapshoty i migracje.
Vault i Consul działają jako niezależne kontenery LXC, uruchomione na różnych węzłach Proxmox (zalecane).
4.2. Model rozmieszczenia
| Usługa |
Kontener LXC |
ID |
Node |
| Consul,Vault |
ubuntu |
ct01005 |
pve-s1 |
| Consul,Vault |
ubuntu |
ct01006 |
pve-s2 |
| Consul,Vault |
ubuntu |
ct01007 |
pve-s3 |
📍
Rozmieszczenie kontenerów na różnych hostach Proxmox minimalizuje ryzyko awarii domenowej.
5. Warstwa aplikacyjna – Consul
5.1. Rola Consul
Consul pełni funkcję:
- backend storage dla Vault,
- mechanizmu koordynacji (leader election),
- systemu utrzymania quorum.
5.2. Tryb pracy
- Klaster Consul składa się z trzech instancji.
- Wymagane quorum: minimum 2/3.
- Komunikacja z Vault odbywa się po HTTPS (
:8501).
📍
Brak quorum Consul skutkuje brakiem możliwości poprawnego działania Vault.
6. Warstwa aplikacyjna – Vault
6.1. Rola Vault
Vault odpowiada za:
- bezpieczne przechowywanie sekretów,
- zarządzanie PKI i certyfikatami,
- wystawianie API do integracji aplikacyjnych.
6.2. Tryb HA
Vault działa w trybie High Availability:
- jeden node aktywny (active),
- pozostałe nody w trybie standby.
📍
Stan aplikacji oraz lock aktywnego noda są przechowywane w Consulu.
7. Komunikacja wewnętrzna Vault ↔ Consul
| Kierunek |
Protokół |
Port |
| Vault → Consul |
HTTPS |
8501 |
Każda instancja Vault komunikuje się z klastrem Consul w celu:
- zapisu i odczytu danych,
- utrzymania locków HA,
- synchronizacji stanu.
8. Wysoka dostępność i odporność na awarie
8.1. Eliminacja SPOF
| Warstwa |
Mechanizm |
| Dostęp zewnętrzny |
VIP + 3× HAProxy |
| Vault |
Active / Standby |
| Storage |
Consul quorum |
| Infrastruktura |
Proxmox + LXC |
8.2. Scenariusze awarii
- Awaria pojedynczego HAProxy → ruch przejmowany przez pozostałe instancje.
- Awaria aktywnego Vault → automatyczne przełączenie na standby.
- Awaria jednego węzła Consul → zachowane quorum.
- Awaria hosta Proxmox → kontenery na pozostałych hostach pozostają dostępne.
2.4 - Gitlab
Architektura GitLab z pula GitLab Runnerów (LXC) z cache NFS
📍 Kontekst
Celem architektury jest zapewnienie spójnego i skalowalnego środowiska CI/CD, które:
- obsługuje jednocześnie self-hosted GitLab CE oraz gitlab.com,
- wykorzystuje pulę wielu runnerów (skalowanie horyzontalne wykonawców),
- posiada współdzielony mechanizm cache dla pipeline’ów oparty o NFS,
- upraszcza zarządzanie artefaktami cache oraz skraca czasy buildów.
flowchart LR
subgraph External["External"]
U["Users"]
end
subgraph Gitlab["GITLAB"]
GITLAB["gitlab-ce"]
GITLAB_COM["gitlab.com"]
end
subgraph RUNNER["GITLAB RUNNERS"]
R1["Gitlab runner s1"]
R2["Gitlab runner s2"]
R3["Gitlab runner s3"]
end
subgraph STORAGE["NFS Storage"]
NFSProd[("NFS Gitlab-Runner<br> Cache")]
NFSProv["NFS Provisioner"]
end
GITLAB == <br> ==> R1
U ==> GITLAB
GITLAB ==> R2 & R3
GITLAB_COM ==> R1 & R2 & R3
R1 == /cache ==> NFSProv
R2 == /cache ==> NFSProv
R3 == /cache ==> NFSProv
NFSProv == /volume1/gitlab-runner ==> NFSProd
style RUNNER fill:#FFF9C4,color:#000000
style STORAGE fill:#FFCDD2,color:#000000
linkStyle 0 stroke:#D50000,fill:none
linkStyle 1 stroke:#00C853,fill:none
linkStyle 2 stroke:#D50000,fill:none
linkStyle 3 stroke:#D50000,fill:none
linkStyle 4 stroke:#AA00FF,fill:none
linkStyle 5 stroke:#AA00FF,fill:none
linkStyle 6 stroke:#AA00FF,fill:none
linkStyle 7 stroke:#FF6D00,fill:none
linkStyle 8 stroke:#FF6D00,fill:none
linkStyle 9 stroke:#FF6D00
linkStyle 10 stroke:#FF6D00
1. Architektura logiczna
Architektura składa się z czterech warstw:
- Warstwa kliencka (External)
- Warstwa GitLab (GitLab CE + gitlab.com)
- Warstwa wykonawcza CI/CD (GitLab Runners)
- Warstwa storage cache (NFS)
2. Warstwa kliencka (External)
2.1. Opis
Warstwa kliencka obejmuje:
- użytkowników (developerów, adminów),
- automaty (np. integracje, webhooki, narzędzia deploymentowe),
- procesy CI/CD inicjowane przez system GitLab.
2.2. Punkt wejścia
Użytkownicy komunikują się z:
- GitLab CE (instancja self-hosted) – interfejs www, API, repozytoria,
- gitlab.com – analogicznie, w zależności od repozytoriów/projektów.
3. Warstwa GitLab
3.1. GitLab CE (self-hosted)
Rola:
- zarządzanie repozytoriami, merge requestami, issue tracking,
- orkiestracja pipeline’ów i kolejkowanie jobów,
- dostarczanie konfiguracji
.gitlab-ci.yml do runnerów,
- dystrybucja zadań do zarejestrowanych wykonawców (runnerów).
Interakcje:
- GitLab CE przydziela zadania do runnerów
R1, R2, R3.
3.2. gitlab.com
Rola:
- publiczna lub osobna instancja GitLab wykorzystywana równolegle,
- możliwość wykorzystywania tej samej puli runnerów (model „shared runners” w ujęciu infrastruktury użytkownika).
Interakcje:
- gitlab.com deleguje zadania do runnerów
R1, R2, R3 (o ile są zarejestrowane do tej instancji).
📍 Uwagi architektoniczne
Jeden runner może być zarejestrowany do wielu instancji, natomiast jest to decyzja operacyjna; wymaga jednoznacznych polityk bezpieczeństwa i separacji (patrz sekcja 10).
4. Warstwa wykonawcza CI/CD – GitLab Runners
4.1. Skład
Warstwa CI/CD obejmuje trzy instancje wykonawcze:
GitLab runner s1 (R1)
GitLab runner s2 (R2)
GitLab runner s3 (R3)
4.2. Rola
Runner odpowiada za:
- pobranie joba z GitLab (CE lub gitlab.com),
- wykonanie joba w wybranym executorze (np. Docker/Shell),
- zarządzanie cache buildów oraz pobieraniem/zapisywaniem cache,
- publikację wyników (logi, statusy, artefakty) do GitLab.
4.3. Skalowanie i dostępność
- Architektura umożliwia skalowanie horyzontalne poprzez dodawanie kolejnych runnerów.
- Awaria pojedynczego runnera zmniejsza przepustowość, ale nie zatrzymuje działania całego CI/CD.
5. Warstwa storage – NFS dla cache
5.1. Cel cache
Cache CI/CD jest wykorzystywany do przechowywania danych pośrednich (np. zależności, paczek, warstw buildów), aby:
- skrócić czas pipeline’ów,
- ograniczyć transfer i liczbę pobrań z Internetu,
- ujednolicić środowisko pracy runnerów.
5.2. Komponenty
📍 NFS
NFS Provisioner:
- udostępnianie wolumenów NFS dla runnerów w formie mountów
/cache,
- zapewnienie „warstwy pośredniej” w zarządzaniu zasobem NFS (zależnie od implementacji: statycznie lub dynamicznie).
NFS Gitlab-Runner Cache
- fizyczny backend danych cache,
- miejsce, gdzie finalnie lądują dane cache utrzymywane dla runnerów.
5.3. Mapowanie montowań
| Runner |
Mount |
Backend |
| R1 |
/cache |
NFS Provisioner → /volume1/cache |
| R2 |
/cache |
NFS Provisioner → /volume1/cache |
| R3 |
/cache |
NFS Provisioner → /volume1/cache |
6. Przepływy (workflow)
6.1. Uruchomienie pipeline (GitLab CE)
- Użytkownik wykonuje push/merge request do GitLab CE.
- GitLab CE tworzy pipeline i planuje joby.
- Jeden z runnerów (R1/R2/R3) pobiera joba.
- Runner wykonuje job i używa
/cache do odczytu/zapisu danych cache.
- Wyniki joba są raportowane do GitLab CE.
6.2. Uruchomienie pipeline (gitlab.com)
Analogicznie, z tą różnicą, że orkiestracja pipeline zachodzi po stronie gitlab.com, natomiast wykonanie joba nadal jest realizowane przez runner’y użytkownika.
7. Wysoka dostępność i odporność na awarie
7.1. Założenia
| Komponent |
Odporność |
| Runners |
odporność przez redundancję (min. 3 instancje) |
| GitLab CE |
zależne od wdrożenia (poza zakresem tego diagramu) |
| Cache NFS |
potencjalny SPOF, zależny od HA NFS (poza zakresem) |
7.2. Krytyczne zależności
📍
Zalecane jest traktowanie NFS cache jako „performance layer”, a nie jako wymogu funkcjonalnego.
8. Wymagania bezpieczeństwa i separacji (zalecenia)
Jeżeli te same runnery obsługują jednocześnie GitLab CE i gitlab.com, należy przyjąć minimalny zestaw zasad:
- separacja runnerów tagami (
tags) i restrykcyjne rules/only po stronie projektów,
- rozdzielenie executorów i środowisk uruchomieniowych (np. różne Docker daemony, izolacja hostów),
- kontrola, co trafia do cache (ryzyko „cache poisoning” między projektami),
- ograniczenie uprawnień runnerów (np. unikanie privileged, ograniczenie mountów hosta),
- rozważenie dedykowanych runnerów dla gitlab.com vs GitLab CE, jeśli wymagania compliance są wysokie.
2.5 - HAProxy
Architektura warstwy HA: VIP + 3× HAProxy dla usług LXC oraz Kubernetes
📍 Kontekst
Celem architektury jest zapewnienie jednolitego, wysoko dostępnego punktu wejścia (VIP) dla usług publikowanych pod domeną *.rachuna-net.pl, w sposób umożliwiający:
-
redundancję warstwy LB (brak SPOF na wejściu),
-
separację i agregację backendów pochodzących z dwóch środowisk:
- LXC (Proxmox): Consul, Vault,
- Kubernetes: Traefik (Ingress), Kubernetes API (masters),
-
centralne sterowanie routowaniem oraz health-checkami.
flowchart LR
subgraph External["External"]
U["Users"]
end
subgraph LB["HA Layer"]
VIP[("VIP")]
HA1["HAProxy 1"]
HA2["HAProxy 2"]
HA3["HAProxy 3"]
end
subgraph CT["LXC"]
CONSUL["Consul"]
VAULT["Vault"]
end
subgraph K8S["Kubernetes"]
T["Traefik"]
M["K8S Masters"]
end
subgraph SERVICES["Services"]
direction TB
CT
K8S
end
U == "<span style=paddK8S-left:><span style=paddK8S-left:>*.rachuna-net.pl</span></span>" ==> VIP
VIP ==> HA1 & HA2 & HA3
HA2 === n1["Small Circle"]
HA1 === n1
HA3 === n1
n1 ==> CONSUL & VAULT & M & T
n1@{ shape: sm-circ}
style CT fill:#FFF9C4,color:#000000
style K8S fill:#C8E6C9,color:#000000
style n1 fill:#D50000,stroke:#D50000
linkStyle 0 stroke:#AA00FF,fill:none
linkStyle 1 stroke:#AA00FF,fill:none
linkStyle 2 stroke:#AA00FF,fill:none
linkStyle 3 stroke:#AA00FF,fill:none
linkStyle 4 stroke:#AA00FF,fill:none
linkStyle 5 stroke:#AA00FF,fill:none
linkStyle 6 stroke:#AA00FF,fill:none
linkStyle 7 stroke:#AA00FF,fill:none
linkStyle 8 stroke:#AA00FF,fill:none
linkStyle 9 stroke:#AA00FF,fill:none
linkStyle 10 stroke:#AA00FF,fill:none
1. Architektura logiczna
Architektura składa się z następujących warstw:
-
External – klienci (użytkownicy, aplikacje)
-
HA Layer – VIP + trzy instancje HAProxy
-
Services – docelowe backendy:
- LXC: Consul, Vault
- Kubernetes: Traefik, Masters (API)
2. Warstwa kliencka (External)
2.1. Opis
Warstwa kliencka obejmuje wszystkie podmioty inicjujące połączenia do usług domenowych.
2.2. Punkt wejścia
Użytkownicy łączą się do usług poprzez:
W praktyce oznacza to, że niezależnie od tego, czy celem jest Vault, Consul, aplikacje w K8S czy API Kubernetes, wejście jest spójne i scentralizowane.
📍
Wyjątkiem jest:
gitlab.rachuna-net.pl,
registry.rachuna-net.pl
*.pages.rachuna-net.pl.
W przyszłości planowane jest przełączenie usług na HAProxy
3. Warstwa HA (VIP + HAProxy)
3.1. VIP (Virtual IP)
VIP stanowi logiczny adres wejściowy, którego zadaniem jest:
- zapewnienie stałego endpointu dla DNS (A/AAAA),
- umożliwienie failover pomiędzy instancjami HAProxy (VRRP/keepalived).
VIP nie realizuje routingu aplikacyjnego; jest jedynie mechanizmem przekierowania do aktywnej instancji warstwy LB.
3.2. HAProxy 1/2/3
Warstwa HA składa się z trzech instancji HAProxy, które zapewniają:
- terminację lub transparentne przekazanie TLS (w zależności od modelu),
- routing ruchu do odpowiednich backendów (LXC/K8S),
- health-check backendów,
- możliwość rozdzielania ruchu po portach (np. 443/8200/8501/6443) oraz po SNI/Host header.
W modelu z diagramu wszystkie instancje HAProxy są równorzędne, a warstwa HA działa jako „klaster” LB.
4. Warstwa usług (Services)
Warstwa usług jest zbiorem backendów pochodzących z dwóch niezależnych domen wykonawczych: LXC i Kubernetes.
4.1. LXC (Proxmox)
W warstwie LXC znajdują się usługi infrastrukturalne:
- Consul – system koordynacji / storage backend (w zależności od wdrożeń),
- Vault – system zarządzania sekretami i certyfikatami.
Warstwa HAProxy publikuje te usługi na zewnątrz zgodnie z polityką portów i nazw.
4.2. Kubernetes
W warstwie Kubernetes znajdują się kluczowe elementy komunikacyjne:
- Traefik – Ingress Controller dla usług aplikacyjnych (HTTP/HTTPS),
- Kubernetes Masters (API) – dostęp do
kube-apiserver (typowo port 6443) dla administracji i automatyzacji klastra.
Warstwa HAProxy może:
- kierować ruch HTTP/HTTPS (443) do Traefik,
- kierować ruch TCP (6443) do API serverów masters.
5. Model routingu (abstrakcja „Service Router”)
📍
Diagram wskazuje logiczny węzeł pośredni (oznaczony jako małe kółko), który reprezentuje koncepcję wspólnego „routera usług” w warstwie HAProxy:
-
jest to abstrakcja, nie osobna maszyna,
-
oznacza, że HAProxy posiada spójny model backendów i reguł routingu,
-
umożliwia kierowanie ruchu do:
- Consul,
- Vault,
- Traefik,
- Kubernetes Masters.
W praktyce realizowane jest to przez konfiguracje HAProxy w postaci:
- wielu frontendów po portach,
- backendów z checkami,
- ewentualnych ACL po SNI/Host.
6. Przepływy ruchu
6.1. Przepływ ogólny
-
Klient inicjuje połączenie do *.rachuna-net.pl.
-
DNS wskazuje na VIP.
-
VIP kieruje ruch do jednej z instancji HAProxy.
-
HAProxy, na podstawie portu i reguł routingu, przekazuje połączenie do właściwego backendu:
- LXC: Vault/Consul,
- K8S: Traefik lub API masters.
6.2. Przykładowe mapowania (typowe)
| Usługa |
Warstwa |
Port wejściowy |
Backend |
| Vault UI/API |
LXC |
8200 lub 443 |
Vault |
| Consul UI/API |
LXC |
8501 lub 443 |
Consul |
| Aplikacje (Ingress) |
K8S |
443 |
Traefik |
| Kubernetes API |
K8S |
6443 |
Masters |
Dokładne porty i tryb TLS zależą od przyjętego standardu publikacji (L4 passthrough vs TLS termination).
7. Wysoka dostępność i odporność na awarie
7.1. Eliminacja SPOF na wejściu
- VIP zapewnia stały endpoint.
- Trzy instancje HAProxy zapewniają redundancję.
7.2. Domena awarii
- awaria pojedynczej instancji HAProxy nie powoduje niedostępności usług,
- awaria pojedynczego backendu (np. Vault node / Traefik pod / master) może być maskowana przez load-balancing i health-checki, o ile backend jest zestawem replik.
2.6 - Kubernetes
Architektura rozwiązania
Wdrożenie klastra Kubernetes zostanie zrealizowane na infrastrukturze Proxmox z uwzględnieniem wysokiej dostępności warstwy sieciowej, control-plane oraz storage. Architektura została podzielona na warstwy funkcjonalne: load balancing, control-plane, worker nodes, storage, ingress, sieć, monitoring, logowanie oraz procesy backup/DR.
Poniższy opis stanowi kompletny model docelowy dla środowiska.
// to do
cert menager, sprzęg z vault
//
flowchart LR
subgraph External["External"]
U["Users"]
end
subgraph LB["HA Layer"]
VIP[("VIP 80 443 6443")]
HA1["HAProxy 1"]
HA2["HAProxy 2"]
HA3["HAProxy 3"]
end
subgraph CP["Control Plane"]
M1["Master 1"]
M2["Master 2"]
M3["Master 3"]
end
subgraph WK["Worker Nodes"]
W1["Worker 1"]
W2["Worker 2"]
W3["Worker 3"]
W4["Worker 4"]
W5["Worker 5"]
W6["Worker 6"]
end
subgraph ING["Ingress Layer"]
T["Traefik"]
end
subgraph SYS["System Components"]
Mon["Monitoring Stack"]
Logs["Logging Stack"]
end
subgraph K8S["Kubernetes Cluster"]
direction TB
CP
WK
ING
SYS
end
subgraph STORAGE["NFS Storage"]
NFSProd[("NFS Export Prod")]
NFSNonProd[("NFS Export NonProd")]
NFSProv["NFS Provisioner"]
end
U --> VIP
VIP --> HA1 & HA2 & HA3
HA1 -- 80 443 --> T
HA1 -- 6443 --> M1
HA2 -- 80 443 --> T
HA2 -- 6443 --> M2
HA3 -- 80 443 --> T
HA3 -- 6443 --> M3
T --> W1 & W2 & W3 & W4 & W5 & W6
NFSProd --> NFSProv
NFSNonProd --> NFSProv
NFSProv --> W1 & W2 & W3 & W4 & W5 & W6
M1 --> Mon & Logs
M2 --> Mon & Logs
M3 --> Mon & Logs
W1 --> Mon & Logs
W2 --> Mon & Logs
W3 --> Mon & Logs
W4 --> Mon & Logs
W5 --> Mon & Logs
W6 --> Mon & Logs
style CP fill:#FFF9C4,color:#000000
style WK fill:#BBDEFB,color:#000000
style ING fill:#C8E6C9,color:#000000
style SYS fill:#E1BEE7,color:#000000
style STORAGE fill:#FFCDD2,color:#000000
style CP fill:#FFF9C4,color:#000000
style WK fill:#BBDEFB,color:#000000
style ING fill:#C8E6C9,color:#000000
style SYS fill:#E1BEE7,color:#000000
style STORAGE fill:#FFCDD2,color:#000000
flowchart LR
U[Users]
subgraph LB[HAProxy layer]
VIP[(VIP)]
HA1[HAProxy_1]
HA2[HAProxy_2]
HA3[HAProxy_3]
end
subgraph K8S[Kubernetes_cluster]
subgraph CP[Control_plane]
M1[Master_1]
M2[Master_2]
M3[Master_3]
end
subgraph WK[Worker_nodes]
W1[Worker_1]
W2[Worker_2]
W3[Worker_3]
W4[Worker_4]
W5[Worker_5]
W6[Worker_6]
end
T[Traefik_ingress]
end
subgraph STORAGE[NFS_server]
NFS1[NFS_exports]
end
subgraph VAULT[Vault_cluster]
V1[Vault_1]
V2[Vault_2]
V3[Vault_3]
end
U --> VIP
VIP --> HA1
VIP --> HA2
VIP --> HA3
VIP --> M1
VIP --> M2
VIP --> M3
HA1 --> T
HA2 --> T
HA3 --> T
T --> W1
T --> W2
T --> W3
T --> W4
T --> W5
T --> W6
W1 --> NFS1
W2 --> NFS1
W3 --> NFS1
W4 --> NFS1
W5 --> NFS1
W6 --> NFS1
W1 --> V1
W2 --> V1
W3 --> V2
W4 --> V2
W5 --> V3
W6 --> V3
Warstwa Load Balancing – HAProxy
Warstwa wejściowa systemu składa się z trzech instancji HAProxy uruchomionych jako maszyny wirtualne, każda na innym węźle Proxmox. HAProxy pełni dwie kluczowe funkcje:
1.1. Balansowanie ruchu do API Kubernetes
- Wszyscy klienci oraz komponenty klastra łączą się z jednym adresem wirtualnym (VIP) obsługiwanym przez HAProxy.
- VIP jest utrzymywany mechanizmem VRRP (keepalived).
- HAProxy kieruje ruch na port 6443 do trzech masternodów.
1.2. Balansowanie ruchu HTTP/HTTPS aplikacji
- Ruch użytkowników trafia do HAProxy, które przekazuje go do Ingress Controllerów (Traefik) działających w klastrze.
- HAProxy pracuje w trybie L4 (TCP passthrough) dla TLS lub L7 dla terminacji TLS – w zależności od scenariusza.
Takie podejście zapewnia wysoki poziom redundancji oraz izolację ruchu przychodzącego.
2. Warstwa Control-Plane – 3× Master
Klaster Kubernetes wykorzystuje trzy węzły master, każdy ulokowany na osobnym węźle fizycznym Proxmox.
Zastosowany model zapewnia:
- pełne HA etcd (quorum 3/3),
- odporność na awarię jednego węzła Proxmox,
- stabilność kontrolera i procesów zarządzających klastrem.
Węzły master pełnią wyłącznie funkcję control-plane (bez uruchamiania workloadów), co zmniejsza ryzyko interferencji oraz upraszcza utrzymanie.
3. Warstwa Worker – 6× Worker Nodes
Warstwa obliczeniowa klastra składa się z sześciu nodów worker, rozmieszczonych równomiernie na węzłach Proxmox.
Założenia:
- nody worker służą do uruchamiania wszystkich aplikacji oraz komponentów systemowych (np. Traefik, Promtail),
- zastosowane będą dedykowane labels/taints dla logicznych podziałów środowisk oraz typów workloadów.
Układ 6 nodów zapewnia elastyczne skalowanie oraz podział obciążeń.
4. Warstwa Storage – NFS z wieloma eksportami
Jako główna warstwa storage wykorzystany zostanie serwer NFS. Architektura przewiduje kilka eksportów, co umożliwia segregację środowisk oraz lepszą kontrolę nad backupami:
/srv/nfs/k8s-prod – dane środowiska produkcyjnego,
/srv/nfs/k8s-nonprod – dane środowisk deweloperskich i testowych.
W klastrze zastosowany zostanie NFS Subdir External Provisioner, tworzący dynamiczne katalogi per PVC.
Dla środowiska przewidziane są oddzielne StorageClass:
Takie podejście zapewnia prosty, stabilny i łatwy do zarządzania system storage.
5. Sieć klastra (CNI) – Calico
W warstwie sieciowej klaster wykorzystuje Calico jako Container Network Interface. Calico zapewnia:
- routing między pods i node’ami,
- wsparcie dla NetworkPolicies,
- wysoką wydajność i stabilność.
Cała komunikacja między node’ami (masters, workers, HAProxy, NFS) odbywa się w jednej sieci L2 Proxmox, co znacząco upraszcza zarządzanie.
6. Warstwa Ingress – Traefik
Klaster wykorzystuje Traefik jako Ingress Controller. Decyzja wynika m.in. z chęci wykorzystania nowoczesnego narzędzia i możliwości rozbudowy o middleware, automatyczne certyfikaty, routing oparty o CRD oraz integrację z HAProxy.
Architektura ruchu:
- Klient → HAProxy (VIP)
- HAProxy → Traefik (NodePort)
- Traefik → Service → Pod
Traefik odpowiada za routing HTTP/HTTPS, rewrites, TLS oraz polityki ruchu.
7. Obserwowalność – lekkie komponenty
7.1. Monitoring
Zastosowane zostaną lekkie komponenty:
- Prometheus (pojedyncza instancja),
- kube-state-metrics,
- metrics-server,
- Grafana (wizualizacja metryk).
Model ten jest wystarczający dla środowiska opartego o Proxmox i ma ograniczone zużycie zasobów.
7.2. Logowanie
Zestaw logowania oparty na:
- Loki (storage logów),
- Promtail (agent logujący na nodach).
Logi aplikacyjne będą dostępne w Grafanie.
8. Backup / Disaster Recovery
Model DR zakłada pełne podejście Infrastructure as Code (IaC):
- Cała infrastruktura (VM-ki Proxmox, konfiguracje sieci) – Terraform.
- Konfiguracja systemowa VM (kubelet, containerd, pakiety) – Ansible.
- Warstwa aplikacyjna K8S (Traefik, monitoring, provisioner NFS, CRD, deployed apps) – Helm/Kustomize w repo Git.
Backup kluczowych elementów:
- backup eksportów NFS (najważniejsze dane – PV),
- okresowy backup etcd,
- przechowywanie manifestów i konfiguracji w repozytoriach Git (GitOps).
Odtworzenie klastra polega na odtworzeniu NFS, ponownym wdrożeniu klastra z IaC oraz podpięciu poprzednich wolumenów.
9. Proces instalacji – kubeadm (bootstrap)
Środowisko jest bootstrappowane narzędziem kubeadm:
kubeadm init na pierwszym masterze z endpointem VIP API (HAProxy).
- Dołączenie pozostałych masterów z
kubeadm join --control-plane.
- Dołączenie workerów.
- Instalacja Calico.
- Instalacja provisionera NFS.
- Instalacja Traefika.
- Instalacja komponentów obserwowalności.
Po etapie bootstrapu klaster może być rozbudowywany automatycznie przez IaC.
Podsumowanie
Przedstawiona architektura rozwiązania opiera się na trzech fundamentalnych filarach: wysoka dostępność, prostota operacyjna oraz możliwość rozwoju.
Trzy HAProxy, trzy master nodes i sześć worker nodes tworzą stabilną i skalowalną podstawę dla aplikacji kontenerowych.
Warstwa storage oparta o NFS jest celowo uproszczona, ale logicznie podzielona tak, aby wspierać porządek środowiskowy i backup.
Wszystkie elementy klastra mogą być utrzymywane, odtwarzane i skalowane w podejściu Infrastructure as Code.
3 - Infrastructure as a Code

Infrastruktura jako kod
📍 Infrastructure as Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
Założenia projektów Infrastructure as a Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym:
- zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
- automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.
Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.
3.1 - Opentofu

IaC za pomocą Opentofu
Opentofu to narzędzie typu Infrastructure as Code (IaC), które umożliwia definiowanie, provisionowanie i zarządzanie infrastrukturą za pomocą plików konfiguracyjnych. Dzięki temu narzędziu możesz w sposób deklaratywny opisywać zasoby, takie jak serwery, sieci czy usługi w chmurze, a następnie automatycznie je tworzyć, modyfikować i usuwać, zapewniając spójność środowisk.
Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.
Założenia projektów Infrastructure as a Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji. Jednym z najczęściej wykorzystywanych narzędzi do implementacji IaC jest Terraform / OpenTofu. Bliźniacze rozwiązania umożliwiają automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.
Wdrażając podejście IaC z użyciem Terraform, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.
Poniżej znajduje się lista projektów Infrastructure as a Code.
| project |
version |
description |
| iac-gitlab |
 |
IAC do zarządzania środowiskiem GitLab. |
| iac-mikrotik |
 |
IAC do zarządzania routerami Mikrotik. |
| iac-proxmox |
 |
IAC do zarządzania środowiskiem Proxmox. |
| iac-vault |
 |
IAC do zarządzania środowiskiem Vault. |
Architektura projektu OpenTofu w pl.rachuna-net
# Przykładowy opis struktury projektu
pl.rachuna-net/infrastructure/opentofu
├── gitlab-profile # Documentation
├── iac-gitlab
├── iac-mikrotik
├── iac-proxmox
├── iac-vault
├── modules # Opentofu modules
│ ├── gitlab-group
│ ├── gitlab-project
│ ├── proxmox-container
│ ├── proxmox-vm
│ ├── routeros-bonding
│ ├── routeros-bridge
│ ├── routeros-dhcp-server
│ ├── routeros-dns
│ ├── routeros-ethernet
│ ├── routeros-system
│ ├── routeros-vlan
│ └── vault-pki
├── proxmox
└── router.rachuna-net.pl
3.1.1 - iac-gitlab

IAC do zarządzania środowiskiem GitLab.
Repozytorum: iac-gitlab
Repozytorium zawierające infrastrukturę jako kod (IaC) do zarządzania środowiskiem GitLab przy użyciu OpenTofu. Umożliwia automatyzację tworzenia, konfiguracji i utrzymania zasobów GitLab.
Architektura rozwiązania
flowchart TB
subgraph s1["opentofu module"]
n2["gitlab-group"]
n1("gitlab-project")
end
A["iac-gitlab"] --> n1
A --> n2
n2@{ shape: rounded}
Przykładowy układ plików
Jak można zauważyć katalogi i pliki odzwierciedlają ułożenie repozytoriów w rzeczywistości.
.
├── data
│ ├── allowed_avatar_group_types.json
│ ├── allowed_avatar_project_types.json
│ ├── allowed_project_types.json
│ ├── group_badges.json
│ └── labels.json
├── _data.tf
├── images
│ ├── group
│ │ └── *.png
│ └── project
│ └── *.png
├── _locals.tf
├── pl.rachuna-net
│ ├── apps
│ │ ├── docs.tf
│ │ └── _locals.tf
│ ├── apps.tf
│ ├── cicd
│ │ ├── gitlab-ci.tf
│ │ └── _locals.tf
│ ├── cicd.tf
│ ├── containers
│ │ ├── buildah.tf
│ │ ├── gohugo.tf
│ │ ├── _locals.tf
│ │ ├── opentofu.tf
│ │ ├── python.tf
│ │ ├── semantic-release.tf
│ │ └── trivy.tf
│ ├── containers.tf
│ ├── infrastructure
│ │ ├── _locals.tf
│ │ ├── opentofu
│ │ │ ├── iac-gitlab.tf
│ │ │ ├── _locals.tf
│ │ │ ├── modules
│ │ │ │ ├── gitlab-group.tf
│ │ │ │ ├── gitlab-project.tf
│ │ │ │ └── _locals.tf
│ │ │ └── modules.tf
│ │ └── opentofu.tf
│ ├── infrastructure.tf
│ └── _locals.tf
├── pl.rachuna-net.tf
└── _providers.tf
3.1.1.1 - Grupy repozytoriów

Tworzenie grupy repozytoriów w GitLab za pomocą OpenTofu

Niniejsza sekcja dokumentacji opisuje proces tworzenia grupy repozytoriów w GitLab przy użyciu OpenTofu. Prezentowane podejście umożliwia automatyczne zarządzanie strukturą repozytoriów, co wspiera podejście Infrastructure as Code (IaC).
Repozytorium GitLab zawierające definicję
🔗 GitLab: pl.rachuna-net/infrastructure/opentofu/iac-gitlab
Repozytorium modułu opentofu - gitlab-group
🔗 GitLab: pl.rachuna-net/infrastructure/opentofu/modules/gitlab-group
Korzyści wynikające z użycia OpenTofu
OpenTofu pozwala na:
- Automatyzację tworzenia i zarządzania grupami repozytoriów,
- Wersjonowanie konfiguracji, co ułatwia kontrolę zmian,
- Powtarzalność konfiguracji, eliminując błędy manualne.
Definiowanie grupy w OpenTofu
Aby utworzyć grupę repozytoriów w GitLab, należy dodać odpowiednią definicję do pliku konfiguracyjnego OpenTofu.
Przykładowy plik konfiguracyjny OpenTofu
Definicja grupy
📄 Ścieżka pliku: pl.rachuna-net/containers.tf
module "_containers" {
source = "git@gitlab.com:pl.rachuna-net/infrastructure/opentofu/modules/gitlab-group.git?ref=v1.0.0"
name = "containers"
description = "Repozytoria z obrazami kontenerowymi."
parent_group = local.parent_name
visibility = "public"
default_branch = "main"
avatar = "containers"
}
module "containers" {
source = "./containers/"
}
Definicja parametrów dla dzieci
📄 Ścieżka pliku: pl.rachuna-net/containers/_locals.tf
locals {
parent_name = "pl.rachuna-net/containers"
project_type = "container"
}
3.1.1.2 - Repozytorium kodu

Tworzenie repozytorium w GitLab za pomocą OpenTofu

Niniejsza sekcja dokumentacji opisuje proces tworzenia repozytoriów w GitLab przy użyciu OpenTofu. Prezentowane podejście umożliwia automatyczne zarządzanie repozytoriami, co wspiera podejście Infrastructure as Code (IaC).
Repozytorium GitLab zawierające definicję
🔗 GitLab: pl.rachuna-net/infrastructure/opentofu/iac-gitlab
Repozytorium modułu opentofu - gitlab-group
🔗 GitLab: pl.rachuna-net/infrastructure/opentofu/modules/gitlab-project
Korzyści wynikające z użycia OpenTofu
OpenTofu pozwala na:
- Automatyzację tworzenia i zarządzania grupami repozytoriów,
- Wersjonowanie konfiguracji, co ułatwia kontrolę zmian,
- Powtarzalność konfiguracji, eliminując błędy manualne.
Definiowanie grupy w OpenTofu
Aby utworzyć repozytorium w GitLab, należy dodać odpowiednią definicję do pliku konfiguracyjnego OpenTofu.
📄 Ścieżka pliku: pl.rachuna-net/containers/opentofu
module "opentofu" {
source = "git@gitlab.com:pl.rachuna-net/infrastructure/opentofu/modules/gitlab-project.git?ref=v1.0.0"
name = "opentofu"
archived = false
description = "Obraz Dockerowy z narzędziem opentofu."
visibility = "public"
tags = ["docker", "opentofu"]
avatar = "opentofu"
parent_group = local.parent_name
project_type = "container"
build_git_strategy = "clone"
gitlab_ci_path = "containers/docker.yml@pl.rachuna-net/cicd/gitlab-ci"
# sonarqube
is_enabled_sonarqube = true
sonarqube_cloud_project_id = "pl.rachuna-net_opentofu"
# mirror to github
mirror_url = format(
"https://%s:%s@github.com/%s/%s.git",
data.vault_kv_secret_v2.github.data["owner"],
data.vault_kv_secret_v2.github.data["token"],
data.vault_kv_secret_v2.github.data["owner"],
"pl.rachuna-net.containers.opentofu"
)
variables = {
PUBLISH_VAULT_SECRET_PATH = {
description = "Ścieżka do sekrety Vault, gdzie będą publikowane zmienne środowiskowe",
value = "pl.rachuna-net/containers/opentofu:CONTAINER_IMAGE_OPENTOFU"
}
PUBLISH_VAULT_VALUE_VARIABLE = {
description = "Nazwa zmiennej środowiskowej, która będzie publikowana w Vault",
value = "CONTAINER_IMAGE_VERSION"
}
}
}
3.1.2 - iac-vault

IAC do zarządzania HashiCorp Vault przy użyciu OpenTofu.
Repozytorium: iac-vault
Repozytorium zawiera kompletną konfigurację Infrastructure as Code (IaC) umożliwiającą zarządzanie środowiskiem HashiCorp Vault za pomocą OpenTofu. Projekt automatyzuje tworzenie, konfigurację oraz utrzymanie komponentów Vault, w tym trzystopniowego PKI, przestrzeni KV oraz polityk dostępu.
Architektura rozwiązania
Repozytorium iac-vault pełni rolę głównego punktu orkiestracji konfiguracji Vault. Bazuje na dedykowanym module vault-pki, który odpowiada za budowę hierarchii certyfikatów.
flowchart TB
subgraph s1["opentofu module"]
n2["vault-pki"]
end
A["iac-vault"] --> n3["auth"] & n4["pki"] & n5["secrets"] & n6["polices"]
n4 --> n2
n2@{ shape: rounded}
Struktura repozytorium:
.
├── auth # mechanizmy autoryzacji (userpass, AppRole)
├── main.tf # główny plik wykonawczy OpenTofu
├── pki # konfiguracja PKI oparta o moduł vault-pki
├── policies # polityki ACL Vault
├── providers.tf # definicje providerów
├── secrets # konfiguracja backendów KV
└── variables.tf # zmienne globalne
Główny plik main.tf integruje moduły:
pki
secrets
policies
auth
Parametry globalne, takie jak var.pki_urls_base (adres publikacji certyfikatów i CRL) oraz var.kv_mount_path, definiowane są w pliku variables.tf.
Public Key Infrastructure (PKI)
Warstwa PKI korzysta z modułu:
👉 vault-pki
Moduł automatyzuje budowę trójwarstwowej hierarchii certyfikatów:
Root CA
pki-root – tworzy główny urząd certyfikacji.
Dwa niezależne urzędy pośrednie, wykorzystywane zgodnie z podziałem ról:
pki-infrastructure – certyfikaty dla infrastruktury (np. routery, systemy HA, bazy danych)
pki-apps – certyfikaty dla aplikacji i usług
Certyfikaty końcowe (leaf)
Moduł pozwala generować certyfikaty końcowe oraz zapisywać je jako sekrety Vault.
Integracja z sekcjami secrets
Wygenerowane certyfikaty mogą być opcjonalnie przechowywane w backendach KV (np. kv-certificates), co umożliwia ich łatwe pobieranie przez inne procesy (np. Ansible, CI/CD).
Polityki dostępu (ACL Policies)
Polityki zdefiniowane są w katalogu policies/ i odpowiadają za granularną kontrolę dostępu do zasobów Vault.
Struktura zawiera m.in.:
Polityki ogólne
full-admin.hcl – pełne uprawnienia administracyjne.
Polityki dla storage KV
kv-devops
kv-gitlab
kv-certificates
Każda z nich definiuje:
- uprawnienia odczytu (
policy_read.hcl)
- uprawnienia zapisu (
policy_write.hcl)
- uprawnienia administracyjne (
policy_admin.hcl)
Polityki dla PKI
pki-root
pki-infrastructure
pki-apps
Zawierają:
- pozwolenia na odczyt CA,
- generowanie CRL,
- wydawanie certyfikatów,
- administrowanie backendem PKI.
Polityki są automatycznie rejestrowane w policies/main.tf.
Auth
Mechanizmy uwierzytelniania znajdują się w katalogu auth/.
Obejmują:
userpass
- zarządzanie użytkownikami Vault,
- definiowanie ról,
- konfigurację dostępu (np. użytkownik
mrachuna).
AppRole
- integracja z CI/CD (np. GitLab CI),
- generowanie ról i secret_id dla pipeline’ów.
Mechanizmy auth są aktywowane i konfigurowane w auth/main.tf.
Podsumowanie
Repozytorium iac-vault zapewnia kompletny, modułowy i skalowalny zestaw IaC do zarządzania HashiCorp Vault w środowisku produkcyjnym. Łączy:
- trzystopniowy PKI,
- kontrolę dostępu,
- storage KV,
- mechanizmy auth,
- dobre praktyki organizacji zasobów w Vault.
Całość jest w pełni automatyzowalna dzięki OpenTofu i integruje się z pipeline’ami GitLab CI oraz procesami konfiguracji (np. Ansible).
3.1.2.1 - Secret storage

Tworzenie storage dla secretów
KV (Key-Value) w HashiCorp Vault to jeden z najprostszych i najczęściej używanych backendów sekretów. Służy do przechowywania dowolnych danych w formie klucz–wartość, takich jak:
- hasła,
- tokeny API,
- klucze prywatne,
- konfiguracje usług,
- certyfikaty,
- dane konfiguracyjne aplikacji.
Sekcja secrets definiuje backendy KV v2 przeznaczone do przechowywania poufnych danych, takich jak:
- konfiguracje projektów,
- tokeny,
- hasła,
- certyfikaty końcowe.
Przykładowa konfiguracja backendu:
resource "vault_mount" "kv_gitlab" {
path = "kv-gitlab"
type = "kv-v2"
description = "Storage for GitLab related secrets"
options = {
version = "2"
type = "kv-v2"
}
}
resource "vault_kv_secret_backend_v2" "kv_gitlab_config" {
mount = vault_mount.kv_gitlab.path
max_versions = 10
cas_required = false
}
3.1.2.2 - PKI

Tworzenie PKI w organizacji
PKI (Public Key Infrastructure) to infrastruktura klucza publicznego – zestaw technologii, zasad i komponentów, które umożliwiają bezpieczną komunikację, uwierzytelnianie i szyfrowanie w systemach informatycznych.
stateDiagram
direction TB
classDef Sky stroke-width:1px,stroke-dasharray:none,stroke:#374D7C,fill:#E2EBFF,color:#374D7C;
classDef Peach stroke-width:1px,stroke-dasharray:none,stroke:#FBB35A,fill:#FFEFDB,color:#8F632D;
[*] --> s1
s1 --> s2
s1 --> s5
s1:Root CA
s1:*.rachuna-net.pl
s2:Infrastructure Intermediate CA
s2:Certyfikaty Infrastruktury
[*]
s5:Apps Intermediate CA
s5:Certyfikaty Aplikacji
class s5 Peach
module "vault_pki" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/vault-pki.git?ref=v1.0.0"
root_domain = "rachuna-net.pl"
root_common_name = "rachuna-net.pl ROOT CA"
pki_urls_base = "https://ct01101.rachuna-net.pl:8200/"
intermediates = {
infrastructure = {
path = "pki-infrastructure"
common_name = "rachuna-net.pl Infrastructure Intermediate CA"
role_name = "infrastructure-default"
}
apps = {
path = "pki-apps"
common_name = "rachuna-net.pl Apps Intermediate CA"
role_name = "apps-default"
}
}
}
Przykładowe rozwiązanie reprezentuje certyfikat główny ROOT CA oraz certyfikaty pośredniczące nfrastructure Intermediate CA dedykowany dla infrastruktury oraz Apps Intermediate CA
Wygenerowanie certyfikatu końcowego
-
Generowanie certyfikaty końcowe (leaf) dla konkretnych usług:
gitlab.rachuna-net.pl
consul.rachuna-net.pl
vault.rachuna-net.pl
docs.rachuna-net.pl
module "vault_pki" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/vault-pki.git?ref=v1.0.0"
root_domain = "rachuna-net.pl"
pki_urls_base = "https://ct01101.rachuna-net.pl:8200/"
intermediates = {
infrastructure = {
path = "pki-infrastructure"
common_name = "Infrastructure Intermediate CA"
role_name = "infrastructure-default"
}
apps = {
path = "pki-apps"
common_name = "Apps Intermediate CA"
role_name = "apps-default"
}
}
leaf_requests = {
"infra-gitlab" = {
backend_key = "infrastructure"
common_name = "gitlab.rachuna-net.pl"
alt_names = [
"registry.rachuna-net.pl"
]
}
"infra-consul" = {
backend_key = "infrastructure"
common_name = "consul.rachuna-net.pl"
alt_names = [
"ct01101.rachuna-net.pl",
"ct01102.rachuna-net.pl",
"ct01103.rachuna-net.pl",
]
}
"infra-vault" = {
backend_key = "infrastructure"
common_name = "vault.rachuna-net.pl"
alt_names = [
"ct01101.rachuna-net.pl",
"ct01102.rachuna-net.pl",
"ct01103.rachuna-net.pl",
]
}
"apps-docs" = {
backend_key = "apps"
common_name = "docs.rachuna-net.pl"
}
}
}
Kluczowe parametry:
-
root_domain = "rachuna-net.pl"
Root CA będzie wystawiony dla tej domeny, np. Rachuna-Net Root CA.
-
pki_urls_base = "https://ct01101.rachuna-net.pl:8200/"
Baza do ustawienia:
issuing_certificates
crl_distribution_points
ocsp_servers
czyli gdzie klienci mają się zgłaszać po CRL / certyfikaty.
-
intermediates – definicja CA pośrednich (mapa):
- klucz (
infrastructure, apps) to alias używany dalej w module,
path – mount w Vault, np. pki-infrastructure,
common_name – CN tego CA,
role_name – domyślna rola w tym backendzie (do wystawiania leafów).
-
leaf_requests – lista certyfikatów końcowych do wygenerowania:
- klucz mapy (
infra-gitlab, infra-consul…) to tylko nazwa logiczna w module,
backend_key – mówi, z którego intermediate CA korzystać (infrastructure / apps),
common_name – CN certyfikatu (zazwyczaj FQDN usługi),
alt_names – Subject Alternative Names (SAN) – dodatkowe nazwy DNS w certyfikacie.
Pobieranie certyfikatu
Zależy, jak moduł jest napisany, ale typowo:
- Zapisane są certyfikaty w
kv (np. kv-certificates/leaf/grafana),
{
"alt_names": [],
"backend_key": "apps",
"ca_chain": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----",
"certificate": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----",
"common_name": "test.rachuna-net.pl",
"issuing_ca": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----",
"private_key": "-----BEGIN RSA PRIVATE KEY-----\n-----END RSA PRIVATE KEY-----",
"serial_number": "42:b5:19:73:cd:f9:70:0c:30:81:93:fb:b5:56:a1:7e:f9:25:6a:23"
}
- bezpośrednio do pobrania z pki
RESP=$(curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"common_name": "grafana.rachuna-net.pl"}' \
https://ct01005.rachuna-net.pl:8200/v1/pki-apps/issue/apps-default)
echo "$RESP" | jq -r '.data.certificate' > grafana.crt
echo "$RESP" | jq -r '.data.private_key' > grafana.key
echo "$RESP" | jq -r '.data.issuing_ca' > grafana.chain.crt
Proponowany podział PKI?
Z poziomu dev/DevOps masz bardzo prosty mentalny model:
-
Root CA – trzymasz w Vault, ale używasz tylko do podpisywania intermediates.
-
Intermediate CA – logiczny podział według typu systemów:
infrastructure: Proxmox, Consul, Vault, GitLab, routery, load balancery.
apps: aplikacje biznesowe, frontend, API.
- (opcjonalnie)
dmz, internal, storage, kubernetes itd.
-
Leaf certyfikaty – dla konkretnych hostów/usług.
I wszystko opisujesz w dwóch mapach: intermediates i leaf_requests.
Przykłady rozbudowania PKI
Kilka konkretnych trików:
-
Osobny intermediate dla Kubernetes:
intermediates = {
# ...
kubernetes = {
path = "pki-k8s"
common_name = "Kubernetes Intermediate CA"
role_name = "k8s-default"
}
}
-
Cert dla Ingress Controller:
leaf_requests = {
"k8s-ingress" = {
backend_key = "kubernetes"
common_name = "ingress.rachuna-net.pl"
alt_names = [
"*.apps.rachuna-net.pl",
]
}
}
Użycie ACME
Ten blok możesz podmienić w sekcji „Utworzenie drzewa certyfikatów Root CA i Intermediate CA” (stary przykład z ref=v1.0.0 → nowy z ref=v1.1.0 + ACME):
module "vault_pki" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/vault-pki.git?ref=v1.1.0"
root_domain = "rachuna-net.pl"
root_common_name = "rachuna-net.pl ROOT CA"
pki_urls_base = "https://ct01005.rachuna-net.pl:8200"
intermediates = {
infrastructure = {
path = "pki-infrastructure"
common_name = "rachuna-net.pl Infrastructure Intermediate CA"
role_name = "infrastructure-default"
# klasyczne parametry PKI
ttl = "26280h"
max_ttl = "26280h"
# konfiguracja ACME dla infrastruktury
acme = {
acme_enabled = true
acme_cluster_path = "https://ct01005.rachuna-net.pl"
allow_wildcard_certificates = true
max_ttl = "168h"
}
# (opcjonalnie) aliasy/parametry dla zachowania wstecznej kompatybilności modułu
acme_enabled = true
acme_cluster_path = "https://ct01005.rachuna-net.pl"
}
apps = {
path = "pki-apps"
common_name = "rachuna-net.pl Apps Intermediate CA"
role_name = "apps-default"
# zezwalamy na wildcardy z tego backendu
allow_wildcard_certificates = true
# klasyczne parametry PKI
ttl = "26h"
max_ttl = "26h"
# konfiguracja ACME dla aplikacji
acme = {
acme_enabled = true
acme_cluster_path = "https://ct01005.rachuna-net.pl"
max_ttl = "25h"
}
}
}
}
3.1.2.3 - Uwierzytelnianie (Auth)

Uwierzytelnianie (Auth)
Uwierzytelnianie (Auth)
Moduł Auth odpowiada za konfigurację metod uwierzytelniania w HashiCorp Vault oraz przypisywanie użytkownikom i procesom automatycznym odpowiednich polityk dostępu (policies).
W projekcie wykorzystywane są dwie główne metody:
- Userpass – dla użytkowników technicznych i administratorów,
- AppRole – dla automatyzacji (CI/CD, GitLab Runner, systemy integracyjne).
1. Polityki (Policies)
Polityki definiują zakres dostępu do ścieżek w Vault. Każda polityka opisuje:
- na jakich ścieżkach (
path)
- jakie operacje (
capabilities)
są dozwolone.
1.1. Minimalny przykład polityki
Plik polityki w formacie HCL:
# policies/app-read.hcl
path "kv-apps/data/apps/example-service" {
capabilities = ["read"]
}
Rejestracja polityki w Vault:
resource "vault_policy" "app_read" {
name = "app-read"
policy = file("${path.module}/policies/app-read.hcl")
}
1.2. Zasady organizacyjne dla polityk
W projekcie polityki są utrzymywane w sposób modułowy w katalogu:
iac-vault/policies/
Struktura:
pki-* – polityki dla PKI,
kv-* – polityki dla KV,
.full-admin – pełne uprawnienia administracyjne.
➡ Każda nowa polityka powinna zostać dodana jako osobny moduł, aby zachować:
- spójność zarządzania,
- możliwość kontroli wersji,
- łatwe przypisywanie do metod uwierzytelniania.
2. Userpass – użytkownicy z przypisanymi politykami
Metoda userpass umożliwia logowanie do Vault za pomocą:
- loginu,
- hasła,
- przypisanych polityk.
2.1. Włączenie metody userpass
resource "vault_auth_backend" "userpass" {
type = "userpass"
}
2.2. Tworzenie użytkownika i przypisywanie polityk
resource "vault_generic_endpoint" "user_jan" {
depends_on = [vault_auth_backend.userpass]
path = "auth/userpass/users/jan"
data_json = jsonencode({
password = "silne-haslo"
policies = [
".full-admin",
"kv-apps.policy_admin"
]
})
}
2.3. Znaczenie pól
| Pole |
Opis |
path |
Ścieżka użytkownika w metodzie userpass |
password |
Hasło użytkownika |
policies |
Lista polityk przypisanych do użytkownika |
✅ Ten mechanizm stosowany jest głównie dla:
- administratorów,
- operatorów,
- użytkowników technicznych.
3. AppRole – tokeny dla automatyzacji (CI/CD, GitLab)
Metoda AppRole przeznaczona jest dla:
- pipeline’ów GitLab,
- narzędzi automatyzujących,
- systemów backendowych.
Logowanie odbywa się przy użyciu:
3.1. Włączenie metody AppRole
resource "vault_auth_backend" "approle" {
type = "approle"
}
3.2. Definicja roli AppRole
resource "vault_approle_auth_backend_role" "ci_role" {
backend = vault_auth_backend.approle.path
role_name = "ci-role"
token_policies = [
"kv-apps.policy_write",
"pki-apps.policy_read"
]
token_ttl = "24h"
token_max_ttl = "24h"
}
3.3. Generowanie secret_id
resource "vault_approle_auth_backend_role_secret_id" "ci_role" {
backend = vault_auth_backend.approle.path
role_name = vault_approle_auth_backend_role.ci_role.role_name
}
3.4. Znaczenie parametrów
| Parametr |
Opis |
role_name |
Nazwa roli używana w automatyzacji |
token_policies |
Polityki przypisane do tokenu |
token_ttl |
Czas życia tokenu |
token_max_ttl |
Maksymalny czas życia tokenu |
secret_id |
Jednorazowy sekret do logowania |
3.1.3 - iac-proxmox

IAC do zarządzania clustrem Proxmox przy użyciu OpenTofu.
Repozytorium: iac-proxmox
Repozytorium zawiera kompletną konfigurację Infrastructure as Code (IaC) umożliwiającą automatyczne, deklaratywne zarządzanie infrastrukturą kontenerową i wirtualną w środowisku Proxmox VE.
Projekt umożliwia:
- tworzenie kontenerów LXC i maszyn wirtualnych w sposób powtarzalny,
- zarządzanie template systemów operacyjnych,
- pełną kontrolę konfiguracji przez Git,
- integrację z Vault w zakresie sekretów,
- eliminację ręcznej konfiguracji przez interfejs graficzny.
Dlaczego LXC zamiast klasycznych maszyn wirtualnych?
Kontenery LXC są w tym projekcie podstawowym mechanizmem uruchamiania usług, ponieważ:
-
uruchamiają się w kilka sekund,
-
zużywają znacznie mniej zasobów niż VM,
-
nie wymagają osobnego jądra systemu,
-
idealnie sprawdzają się dla:
- mikroserwisów,
- reverse proxy,
- workerów CI,
- systemów backendowych.
Maszyny wirtualne są stosowane wyłącznie tam, gdzie:
- wymagane jest osobne jądro,
- potrzebna jest pełna izolacja sprzętowa.
5. Struktura projektu iac-proxmox
Uproszczona struktura repozytorium:
iac-proxmox/
├── containers_templates/ # Szablony LXC
├── machines/ # Definicje kontenerów LXC i VM (ctXXXXX.tf)
├── _locals.tf # Wspólne zmienne (storage, node, pool)
└── main.tf
Integracja z Vault
Projekt iac-proxmox jest w pełni zintegrowany z Vault, który przechowuje m.in.:
- hasła root,
- dane użytkowników technicznych,
- klucze SSH,
- adresy IP.
Dzięki temu:
- ❌ dane dostępowe nie trafiają do repozytorium,
- ✅ możliwa jest rotacja sekretów,
- ✅ dostęp do infrastruktury jest audytowalny.
3.1.3.1 - Pobieranie template LXC

Pobieranie template LXC
Instrukcja pobrania szablonu LXC oraz jego wykorzystania do utworzenia kontenera w projekcie iac-proxmox przy użyciu modułu proxmox-container.
1. Cel i kontekst
Szablony LXC (templates) w środowisku Proxmox VE są wykorzystywane do szybkiego i powtarzalnego tworzenia kontenerów systemowych.
W projekcie iac-proxmox za pobieranie oraz utrzymanie tych szablonów odpowiada dedykowany katalog:
./containers_templates/
Zasoby zdefiniowane w tym katalogu:
- automatycznie pobierają obrazy kontenerów,
- zapisują je w magazynie danych Proxmoxa,
- udostępniają je do dalszego użycia przez moduł
proxmox-container.
2. Pobranie szablonu LXC
Poniższy zasób odpowiada za pobranie oficjalnego szablonu Ubuntu 24.04 LTS bezpośrednio z repozytorium Proxmoxa:
resource "proxmox_virtual_environment_download_file" "ubuntu24-10" {
content_type = "vztmpl"
datastore_id = local.storage_name
node_name = local.default_node
file_name = "ubuntu-24.04.tar.zst"
url = "http://download.proxmox.com/images/system/ubuntu-24.04-standard_24.04-2_amd64.tar.zst"
checksum = "4030982618eeae70854e8f9711adbd09"
checksum_algorithm = "md5"
}
3. Omówienie parametrów zasobu
| Parametr |
Opis |
content_type |
Typ pobieranego pliku — vztmpl oznacza szablon LXC |
datastore_id |
Magazyn danych w Proxmoxie (np. local, local-lvm, ceph) |
node_name |
Nazwa noda Proxmoxa, na którym ma zostać zapisany template |
file_name |
Nazwa pliku po zapisaniu w repozytorium template |
url |
Bezpośredni adres oficjalnego szablonu |
checksum |
Suma kontrolna pliku |
checksum_algorithm |
Algorytm weryfikacji integralności (md5, sha256) |
✅ Dzięki zastosowaniu checksum OpenTofu weryfikuje, czy pobrany plik nie został uszkodzony.
4. Zmienne lokalne wykorzystywane w zasobie
Zmienna local.storage_name oraz local.default_node są zwykle zdefiniowane w pliku:
locals.tf
Przykładowa definicja:
locals {
storage_name = "local"
default_node = "proxmox-1"
}
✅ Takie podejście zapewnia:
- centralne zarządzanie konfiguracją,
- łatwą migrację między środowiskami,
- brak twardo zakodowanych nazw w zasobach.
5. Zależność od modułu proxmox-container
Po pobraniu szablonu, może on zostać wykorzystany w module:
modules/proxmox-container
Przykład użycia template w definicji kontenera:
template = "local:vztmpl/ubuntu-24.04.tar.zst"
Moduł proxmox-container wykorzystuje ten template do:
- utworzenia systemu plików kontenera,
- konfiguracji sieci,
- ustawienia użytkowników,
- przypisania zasobów CPU i RAM.
3.1.3.2 - Kontener LXC

Kontener LXC
LXC (Linux Containers) to technologia lekkiej wirtualizacji na poziomie systemu operacyjnego, umożliwiająca uruchamianie wielu odseparowanych środowisk Linux na jednym jądrze systemowym.
W przeciwieństwie do klasycznych maszyn wirtualnych:
- nie emuluje pełnego sprzętu,
- nie wymaga osobnego jądra systemu,
- zużywa znacznie mniej zasobów,
- uruchamia się niemal natychmiastowo.
W środowisku Proxmox VE kontenery LXC są wykorzystywane do:
- uruchamiania mikroserwisów,
- hostowania aplikacji backendowych,
- serwerów proxy, API, workerów CI,
- środowisk testowych i stagingowych.
✅ LXC to rozwiązanie:
- szybsze niż VM,
- tańsze zasobowo,
- idealne do infrastruktury jako kod (IaC).
1. Rola kontenerów LXC w iac-proxmox
W projekcie iac-proxmox kontenery LXC są:
- w pełni zarządzane przez OpenTofu,
- tworzone automatycznie z gotowych template,
- konfigurowane przez moduł:
modules/proxmox-container
Każdy kontener posiada:
- jednoznaczny CT ID,
- przypisany node, storage, pool,
- zdefiniowane zasoby CPU, RAM i dysk,
- użytkownika technicznego,
- klucz SSH.
2. Struktura katalogów dla kontenerów
Definicje kontenerów znajdują się w katalogu:
./machines/
Każdy kontener posiada osobny plik:
ctXXXXX.tf
Przykład:
ct01011.tf
✅ Zapewnia to:
- czytelność,
- pełną niezależność kontenerów,
- łatwą kontrolę zmian w Git.
3. Tworzenie kontenera LXC
module "ct01011" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/proxmox-container.git?ref=v1.0.0"
hostname = "ct01011.rachuna-net.pl"
description = "example-service"
node_name = "pve-s1"
ct_id = 1011
pool_id = "web-proxy"
start_on_boot = true
tags = ["example", "ubuntu"]
cpu_cores = 2
memory = { dedicated = 2048, swap = 1024 }
disk = { storage_name = "local-lvm", disk_size = 32 }
operating_system = {
template_file = "local:vztmpl/ubuntu-24.04.tar.zst"
type = "ubuntu"
}
user_account = {
username = "techuser"
password = "change-me"
public_ssh_key = "ssh-ed25519 AAAA..."
}
}
4. Omówienie kluczowych parametrów
4.1. Identyfikacja i lokalizacja
| Parametr |
Opis |
hostname |
Pełna nazwa DNS kontenera |
description |
Opis techniczny usługi |
node_name |
Węzeł Proxmoxa |
ct_id |
Unikalne ID kontenera |
pool_id |
Pool logiczny |
start_on_boot |
Autostart po restarcie |
tags |
Tagi administracyjne |
4.2. Zasoby sprzętowe
cpu_cores = 2
memory = {
dedicated = 2048
swap = 1024
}
disk = {
storage_name = "local-lvm"
disk_size = 32
}
✅ Pozwala to precyzyjnie sterować:
- obciążeniem hosta,
- wydajnością usług,
- dynamicznym skalowaniem.
4.3. System operacyjny
operating_system = {
template_file = "local:vztmpl/ubuntu-24.04.tar.zst"
type = "ubuntu"
}
✅ Template musi być:
- wcześniej pobrany przez
containers_templates,
- dostępny na storage Proxmoxa.
4.4. Konto użytkownika
user_account = {
username = "techuser"
password = "change-me"
public_ssh_key = "ssh-ed25519 AAAA..."
}
✅ Tworzone automatycznie:
- konto techniczne,
- dostęp SSH,
- możliwość wyłączenia logowania root.
5. Integracja z Vault
Jeżeli dane dostępowe pochodzą z Vault, zamiast jawnych wartości:
user_account = {
username = data.vault_kv_secret_v2.ct.data["username"]
password = data.vault_kv_secret_v2.ct.data["password"]
public_ssh_key = data.vault_kv_secret_v2.ct.data["ssh_key"]
}
✅ Pozwala to:
- usunąć hasła z repozytorium,
- rotować dane dostępowe,
- centralnie kontrolować dostęp.
3.1.3.3 - Virtual Machine

Maszyny wirtualne
Wirtualna maszyna (VM, Virtual Machine) to programowe odwzorowanie fizycznego komputera, które działa w ramach istniejącego systemu lub bezpośrednio na hyperwizorze. Posiada własny system operacyjny, przydzielone zasoby (CPU, pamięć RAM, dysk, sieć) i jest odizolowana od innych maszyn działających na tym samym hoście. Dzięki wirtualizacji możliwe jest uruchamianie wielu niezależnych środowisk na jednej fizycznej infrastrukturze, co zwiększa efektywność wykorzystania zasobów, ułatwia zarządzanie oraz podnosi bezpieczeństwo i elastyczność środowisk IT.
1. Struktura katalogów dla kontenerów
Definicje vm znajdują się w katalogu:
./machines/
Każdy vm posiada osobny plik:
vmXXXXX.tf
Przykład:
vm01011.tf
✅ Zapewnia to:
- czytelność,
- pełną niezależność kontenerów,
- łatwą kontrolę zmian w Git.
2. Tworzenie VM
module "vm01017" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/proxmox-vm.git?ref=v1.0.0"
hostname = "vm01017.rachuna-net.pl"
description = "Kubernetes master w4"
node_name = "pve-s1"
vm_id = 1017
pool_id = "kubernetes"
protection = true
tags = ["kubernetes", "master", "ubuntu"]
is_dmz = false
mac_address = "BC:24:11:50:5F:83"
datastore_id = "storage.rachuna-net.pl"
template = {
node_name = "pve-s1"
vm_id = 901
full = true
}
cpu = {
cores = 4
sockets = 2
}
memory = {
dedicated = 8192
}
user_account = {
username = data.vault_kv_secret_v2.auth_techuser.data["username"]
password = data.vault_kv_secret_v2.auth_techuser.data["password"]
public_ssh_key = data.vault_kv_secret_v2.auth_techuser.data["public_ssh_key"]
}
vault = {
mount = "kv-gitlab"
path = "pl.rachuna-net/infrastructure/opentofu/iac-proxmox/machine/vm01017"
}
}
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/proxmox-vm.git?ref=v1.0.0" - Źródło modułu.
hostname – pełna nazwa FQDN VM.
description – krótki opis roli serwera (widzoczny w Proxmox).
node_name – węzeł Proxmox, na którym VM ma być tworzona (pve-s1, pve-s2, pve-s3, …).
vm_id – unikalny ID VM w klastrze (sprawdź, czy numer nie jest zajęty).
pool_id – pula Proxmox (np. kubernetes), ustaw zgodnie z przeznaczeniem.
protection – zwykle true dla ochrony przed przypadkowym usunięciem.
tags – lista tagów (rola, system, np. ["kubernetes", "master", "ubuntu"]).
is_dmz – true/false zależnie od strefy sieci.
mac_address – statyczny MAC (zapewnij unikalność w sieci).
datastore_id – magazyn na dyski (obecnie storage.rachuna-net.pl jak w istniejących VM).
2.1. Sekcje template, cpu, memory
template – wskaż template VM (aktualnie wykorzystywany jest vm_id = 901 na pve-s1 z kopią pełną: full = true).
cpu – ustaw liczbę rdzeni (cores) i gniazd (sockets).
memory – dedicated w MB (np. 8192).
2.2. Dostępy i sekrety
user_account pobiera dane użytkownika technicznego z Vault: data.vault_kv_secret_v2.auth_techuser.data[...] – upewnij się, że wpis istnieje (definicja w machines/_data.tf).
vault – ustaw ścieżkę na sekrety specyficzne dla VM, zgodnie z konwencją pl.rachuna-net/infrastructure/opentofu/iac-proxmox/machine/vmNNNNN (zaktualizuj numer).
3. Integracja z Vault
Jeżeli dane dostępowe pochodzą z Vault, zamiast jawnych wartości:
user_account = {
username = data.vault_kv_secret_v2.ct.data["username"]
password = data.vault_kv_secret_v2.ct.data["password"]
public_ssh_key = data.vault_kv_secret_v2.ct.data["ssh_key"]
}
✅ Pozwala to:
- usunąć hasła z repozytorium,
- rotować dane dostępowe,
- centralnie kontrolować dostęp.
3.1.4 - iac-mikrotik

IAC do zarządzania routerami MikroTik przy użyciu OpenTofu.
Repozytorium:
iac-mikrotik
Repozytorium zawiera kompletną konfigurację Infrastructure as Code (IaC) umożliwiającą automatyczne, deklaratywne zarządzanie konfiguracją routerów MikroTik działających na systemie RouterOS przy użyciu OpenTofu.
Projekt umożliwia:
- pełne zarządzanie warstwą L2/L3 w sposób deklaratywny,
- automatyzację konfiguracji interfejsów, VLAN, bridge oraz bondingu (LACP),
- centralne zarządzanie serwerami DHCP i DNS,
- utrzymanie statycznych rekordów DNS dla infrastruktury krytycznej,
- eliminację ręcznej konfiguracji przez interfejs graficzny RouterOS,
- wersjonowanie, audyt oraz szybki rollback zmian przez Git.
Cel projektu iac-mikrotik
Celem projektu jest zbudowanie spójnego, audytowalnego i w pełni zautomatyzowanego modelu zarządzania konfiguracją sieciową, obejmującego:
- routing,
- switching,
- adresację IP,
- segmentację VLAN,
- serwery DHCP,
- centralny resolver DNS.
Projekt stanowi fundament całej warstwy sieciowej dla środowisk:
- Proxmox,
- usług serwerowych,
- środowisk developerskich,
- sieci Wi-Fi,
- stref DMZ i management.
Zakres dokumentacji
Dokumentacja obejmuje pełen cykl życia konfiguracji RouterOS:
-
Interfaces – Ethernet, Bonding (LACP), Bridge, VLAN
(każdy typ jako osobny moduł i katalog konfiguracyjny),
-
Serwery DHCP – sieci, pule adresowe, serwery DHCP, statyczne rezerwacje, integracja z DNS,
-
Serwer DNS – centralny resolver, cache, parametry upstream, bezpieczeństwo,
-
Rekordy DNS – statyczne wpisy:
A, AAAA,
CNAME,
TXT,
MX,
NS,
utrzymywane centralnie w mapie dns_records.
Struktura katalogów w repozytorium
Uproszczona struktura projektu:
router.rachuna-net.pl/
├── interfaces/ # ethernet, bonding, bridge, vlan (*.tf)
├── dhcp-servers/ # każdy serwer DHCP w osobnym pliku
├── dns-server/ # main.tf z konfiguracją resolvera
└── dns-records/ # mapa statycznych rekordów DNS
Zasady organizacyjne:
- ✅ jeden plik = jeden element logiczny,
- ✅ brak plików „kombajnów”,
- ✅ pełna czytelność konfiguracji,
- ✅ jednoznaczne mapowanie kod → element infrastruktury.
Moduły OpenTofu wykorzystywane w projekcie
Warstwa interfejsów:
routeros-ethernet
routeros-bonding
routeros-bridge
routeros-vlan
Warstwa usług IP:
routeros-dhcp-server – sieci, pule, serwery DHCP oraz statyczne leases,
routeros-dns – resolver, cache, serwery upstream oraz statyczne dns_records.
Każdy moduł odpowiada za jedną, ściśle określoną funkcję logiczną, co umożliwia:
- precyzyjny audyt zmian,
- łatwą rozbudowę,
- bezpieczny rollback.
Kolejność wdrażania konfiguracji
Zalecana kolejność wdrożeń w iac-mikrotik:
- Interfaces
Ethernet → Bonding → Bridge → VLAN
- Serwery DHCP
Na gotowych interfejsach L3
- Serwer DNS
Resolver + cache
- Rekordy DNS
Statyczne wpisy dla infrastruktury krytycznej
Taka kolejność eliminuje błędy zależności między warstwami.
Wspólne zasady projektowe
- ✅ Zero konfiguracji w GUI – całość wyłącznie przez IaC,
- ✅ Jeden moduł = jedna funkcja logiczna,
- ✅ DHCP zawsze wskazuje lokalny DNS,
- ✅ Krytyczne hosty zawsze posiadają statyczne rekordy DNS,
- ✅ Każda zmiana przechodzi przez Git (review, audyt, rollback),
- ❌ Brak ręcznych modyfikacji w RouterOS,
- ❌ Brak przechowywania konfiguracji poza repozytorium.
3.1.4.1 - Konfiguracja Interfaces

Konfiguracja Interfaces
Dokumentacja opisuje zarządzanie interfejsami sieciowymi w routerach MikroTik z wykorzystaniem RouterOS oraz OpenTofu w podejściu Infrastructure as Code (IaC).
Celem tej sekcji jest ujednolicenie oraz pełna automatyzacja konfiguracji interfejsów sieciowych w infrastrukturze RouterOS. Dokumentacja obejmuje:
- porty Ethernet,
- interfejsy Bonding (LACP),
- mosty logiczne Bridge,
- sieci wirtualne VLAN.
Każdy typ interfejsu:
- jest zarządzany przez dedykowany moduł OpenTofu,
- posiada własny katalog konfiguracyjny,
- może być wersjonowany i audytowany w systemie kontroli wersji.
1. Struktura katalogów
Konfiguracja interfejsów znajduje się w:
router.rachuna-net.pl/interfaces/
├── ethernet/
├── bonding/
├── bridge/
└── vlan/
Zasada organizacyjna:
✅ jeden plik = jedna logiczna konfiguracja
✅ brak konfiguracji w GUI
✅ pełna powtarzalność konfiguracji
2. Konfiguracja Ethernet
Pliki znajdują się w:
router.rachuna-net.pl/interfaces/ethernet/*.tf
Przykładowa konfiguracja
module "ethernet_ether1" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-ethernet.git?ref=v1.0.0"
name = "ether1"
mtu = 1500
arp = "enabled"
poe_out = "off"
disabled = false
dhcp_client = false
addresses = ["192.0.2.1/24"] # lub puste, jeśli tylko do bridge/bonding
}
Znaczenie parametrów
| Parametr |
Opis |
name |
Nazwa fizycznego portu |
mtu |
Rozmiar ramki |
arp |
Obsługa ARP |
poe_out |
Zasilanie PoE |
disabled |
Włączenie/wyłączenie portu |
dhcp_client |
Czy uruchomić klienta DHCP |
addresses |
Adresy IP przypisane do portu |
3. Bonding – agregacja łączy (LACP)
Bonding (Link Aggregation)
Bonding to mechanizm łączenia kilku fizycznych interfejsów sieciowych w jeden logiczny interfejs, którego celem jest:
- zwiększenie przepustowości łącza,
- zapewnienie redundancji połączenia,
- poprawa dostępności infrastruktury sieciowej.
W systemie RouterOS bonding realizowany jest na poziomie sterownika sieciowego i działa w warstwie L2 (Data Link Layer) modelu OSI.
Cele stosowania bondingu
Bonding znajduje zastosowanie wszędzie tam, gdzie wymagane są:
- ✅ wysokie przepustowości (uplinki, storage, serwery),
- ✅ odporność na awarie pojedynczego portu,
- ✅ równoważenie ruchu sieciowego,
- ✅ konsolidacja wielu łączy w jeden kanał logiczny.
Typowe przypadki użycia:
- połączenia do macierzy dyskowych,
- uplinki do switchy rdzeniowych,
- połączenia router–serwer,
- trunk pod VLAN dla wirtualizacji.
Pliki znajdują się w:
interfaces/bonding/*.tf
Przykład (tryb LACP – 802.3ad):
module "bonding_storage" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-bonding.git?ref=v1.0.0"
name = "bond-storage"
mode = "802.3ad"
slaves = ["ether2", "ether3"]
lacp_rate = "1sec"
arp = "enabled"
comment = "storage uplink"
}
Znaczenie parametrów
| Parametr |
Opis |
name |
Nazwa interfejsu logicznego |
mode |
Tryb pracy (np. 802.3ad) |
slaves |
Lista portów fizycznych |
lacp_rate |
Częstotliwość LACP |
arp |
Obsługa ARP |
comment |
Opis administracyjny |
4. Bridge
Most sieciowy (Bridge)
Bridge to logiczny przełącznik sieciowy warstwy drugiej (L2 – Data Link Layer), który łączy wiele interfejsów sieciowych w jedną wspólną domenę rozgłoszeniową (broadcast domain).
W systemie RouterOS bridge pełni rolę wirtualnego switcha programowego.
Bridge umożliwia:
- przełączanie ramek na podstawie adresów MAC,
- łączenie wielu portów fizycznych w jedną sieć logiczną,
- obsługę VLAN,
- kontrolę topologii przez protokoły STP / RSTP / MSTP.
Główne zadania bridge
Bridge odpowiada za:
-
✅ przełączanie ruchu między portami LAN,
-
✅ budowanie segmentów sieci warstwy drugiej,
-
✅ rozdział ruchu pomiędzy VLAN,
-
✅ integrację:
- Ethernet,
- bonding,
- VLAN,
- interfejsów wirtualnych.
Pliki znajdują się w:
interfaces/bridge/*.tf
Przykład:
module "bridge_clients" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-bridge.git?ref=v1.0.0"
name = "br-clients"
comment = "bridge klientów"
ageing = 300
protocol_mode = "rstp"
ports = [
{ interface = "ether4", pvid = 10 },
{ interface = "ether5", pvid = 10 }
]
}
Znaczenie parametrów
| Parametr |
Opis |
name |
Nazwa bridge |
comment |
Opis |
ageing |
Czas życia wpisów MAC |
protocol_mode |
Tryb STP |
ports |
Lista portów wraz z PVID |
4. VLAN – sieci logiczne
VLAN (Virtual Local Area Network)
VLAN (Virtual Local Area Network) to mechanizm logicznego podziału jednej fizycznej infrastruktury sieciowej na wiele odseparowanych sieci warstwy drugiej (L2).
Dzięki VLAN możliwe jest tworzenie niezależnych segmentów sieci bez konieczności stosowania osobnych urządzeń fizycznych.
W systemie RouterOS VLAN realizowany jest jako wirtualny interfejs przypisany do istniejącego interfejsu fizycznego, bondingu lub bridge.
Główne cele stosowania VLAN
VLAN stosuje się w celu:
- ✅ separacji ruchu sieciowego,
- ✅ zwiększenia bezpieczeństwa,
- ✅ segmentacji infrastruktury,
- ✅ ograniczenia rozgłoszeń (broadcast),
- ✅ logicznego podziału sieci według przeznaczenia.
Typowe zastosowania:
- VLAN dla użytkowników,
- VLAN dla serwerów i maszyn wirtualnych,
- VLAN dla storage,
- VLAN dla Wi-Fi,
- VLAN dla zarządzania (management).
Pliki znajdują się w:
interfaces/vlan/*.tf
Przykład:
module "vlan_vms_internal" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-vlan.git?ref=v1.0.0"
name = "vlan-vms-int"
interface = "bond-storage" # trunk/bond/ether/bridge
vlan_id = 20
arp = "enabled"
mtu = 1500
loop_protect = false
comment = "VLAN VMs internal"
}
Znaczenie parametrów
| Parametr |
Opis |
name |
Nazwa interfejsu VLAN |
interface |
Interfejs nadrzędny |
vlan_id |
Identyfikator VLAN |
arp |
Obsługa ARP |
mtu |
MTU |
loop_protect |
Ochrona przed pętlą |
comment |
Opis sieci |
5. Kolejność wdrażania konfiguracji
Zalecana kolejność:
- Ethernet
- Bonding
- Bridge
- VLAN
Zapobiega to błędom zależności i brakującym interfejsom
3.1.4.2 - Serwery DHCP

Konfiguracja Serwerów DHCP
DHCP (Dynamic Host Configuration Protocol) to protokół sieciowy działający w warstwie L3 modelu OSI, którego celem jest automatyczne przydzielanie parametrów sieciowych hostom, takich jak:
- adres IP,
- maska podsieci,
- adres bramy (gateway),
- serwery DNS,
- domena wyszukiwania,
- czas dzierżawy adresu (lease time).
Architektura serwera DHCP w projekcie iac-mikrotik
Konfiguracja DHCP składa się z kilku warstw logicznych:
-
Interfejs L3, na którym działa DHCP
(np. BRIDGE-PROXMOX lub interfejs VLAN)
-
Sieć DHCP (dhcp_network)
definiuje:
- adresację,
- bramę,
- serwery DNS,
- domenę.
-
Pula adresowa (address_pools)
zakresy IP do automatycznego przydziału.
-
Serwer DHCP (dhcp-server)
instancja działająca na wybranym interfejsie.
-
Leases (dhcp_leases)
statyczne rezerwacje IP na podstawie MAC.
Struktura plików
Konfiguracja DHCP znajduje się w katalogu:
router.rachuna-net.pl/dhcp-servers/*.tf
Każdy serwer DHCP powinien być definiowany w osobnym pliku.
Zalety:
- wersjonowanie każdej podsieci,
- audyt zmian,
- możliwość rollback,
- czysta i modularna struktura projektu.
Przykład konfiguracji serwera DHCP
Poniżej pełen przykład wdrożenia serwera DHCP dla sieci Proxmox:
module "dhcp-proxmox" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-dhcp-server.git?ref=v1.0.0"
name = "DHCP-PROXMOX"
comment = "DHCP server for PROXMOX"
address_pool = "PROXMOX-POOLS"
interface = "BRIDGE-PROXMOX"
lease_time = "12h"
dhcp_network = {
address = "10.3.0.0/24"
gateway = "10.3.0.1"
dns_server = ["10.3.0.1"]
domain = "rachuna-net.pl"
comment = "proxmox network"
}
address_pools = {
"PROXMOX-POOLS" = {
ranges = ["10.3.0.11-10.3.0.14"]
comment = "proxmox pool"
}
}
dhcp_leases = {
"10.3.0.11" = {
hostname = "pve-s1.rachuna-net.pl"
comment = "pve-s1.rachuna-net.pl"
mac_address = "38:05:25:33:B8:49"
server = "DHCP-PROXMOX"
disabled = false
}
"10.3.0.12" = {
hostname = "pve-s2.rachuna-net.pl"
comment = "pve-s2.rachuna-net.pl"
mac_address = "D8:5E:D3:6B:3F:0C"
server = "DHCP-PROXMOX"
disabled = false
}
"10.3.0.13" = {
hostname = "pve-s3.rachuna-net.pl"
comment = "pve-s3.rachuna-net.pl"
mac_address = "18:C0:4D:8C:4F:5E"
server = "DHCP-PROXMOX"
disabled = false
}
}
}
Omówienie parametrów technicznych
5.1. Parametry serwera DHCP
| Parametr |
Znaczenie |
name |
Nazwa instancji serwera DHCP |
comment |
Opis techniczny |
address_pool |
Nazwa puli adresowej używanej przez serwer |
interface |
Interfejs, na którym działa DHCP (bridge lub VLAN) |
lease_time |
Czas ważności wydawanej dzierżawy IP |
5.2. Sieć DHCP
Sekcja dhcp_network jest kluczowa – definiuje parametry, które klient otrzyma w komunikacie DHCP OFFER:
| Parametr |
Opis |
address |
Zakres sieci (subnet) |
gateway |
Brama (router) |
dns_server |
Lista serwerów DNS |
domain |
Domena dla FQDN |
comment |
Opis |
5.3. Pula adresowa (dynamiczne przydzielanie IP)
| Parametr |
Opis |
ranges |
Zakresy IP do automatycznego przydzielania |
comment |
Opis techniczny puli |
Każda pula posiada nazwę klucza — np.:
"PROXMOX-POOLS"
5.4. Leases (statyczne przypisania)
Zalecane w serwerowniach, hypervisorach, NAS, firewallach.
| Parametr |
Opis |
hostname |
Nazwa klienta |
mac_address |
Adres MAC urządzenia |
server |
Instancja DHCP, która będzie zarządzać lease |
disabled |
Włączenie/wyłączenie rezerwacji |
Zasady projektowe i dobre praktyki
1. Ogólne zasady
- Każda podsieć = osobny moduł DHCP
- DHCP musi działać tylko na interfejsach L3
- Nigdy nie mieszaj DHCP z adresacją statyczną w tej samej puli
- Węzły Proxmox, Routery, Nas’y – zawsze na statycznych lease
2. Bezpieczeństwo
3. Integracja z DNS
W RouterOS serwer DHCP może dynamicznie rejestrować hosty w DNS.
Pole hostname w lease jest automatycznie używane do:
- zapisu rekordów A,
- aktualizacji rekordów PTR.
Typowe błędy i jak ich unikać
| Problem |
Przyczyna |
Rozwiązanie |
| Klient nie dostaje IP |
DHCP działa na złym interfejsie |
Upewnij się, że interfejs posiada IP i jest L3 |
| IP spoza zakresu |
Nakładanie się pul |
Rozdziel pule dynamiczne i statyczne |
| Błędne DNS |
Nieprawidłowe wpisy dns_server |
Zastosuj lokalny DNS routera lub upstream |
| Lease się nie odświeża |
Zbyt krótki lease_time |
Zwiększ do 12–24h |
Podsumowanie
Serwer DHCP w iac-mikrotik zapewnia:
- deklaratywne, w pełni automatyczne zarządzanie adresacją,
- wersjonowanie zmian w Git,
- spójność konfiguracji RouterOS,
- łatwe wdrażanie i modyfikowanie pul IP,
- centralne rezerwacje dla serwerów i hostów krytycznych.
3.1.4.3 - Serwer DNS

Konfiguracja Serwera DNS
DNS (Domain Name System) to podstawowy mechanizm infrastruktury sieciowej odpowiedzialny za zamianę nazw domenowych na adresy IP (forward lookup) oraz adresów IP na nazwy domenowe (reverse lookup – rekordy PTR).
W projekcie iac-mikrotik serwer DNS oparty jest o resolver systemu RouterOS i zarządzany deklaratywnie przy użyciu OpenTofu.
Struktura plików
Konfiguracja DNS znajduje się w katalogu:
router.rachuna-net.pl/dns-server/main.tf
Zalety takiego podejścia:
- centralne zarządzanie resolverem,
- wersjonowanie konfiguracji,
- szybki rollback,
- spójność dla całego środowiska.
Przykład konfiguracji serwera DNS
module "dns_server" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/routeros-dns.git?ref=v1.0.0"
allow_remote_requests = true
cache_max_ttl = "1d"
max_concurrent_queries = 1000
servers = ["1.1.1.1", "8.8.8.8"]
dynamic_servers = []
comment = "DNS resolver/router"
}
Omówienie parametrów technicznych
1. Parametry instancji serwera DNS
| Parametr |
Znaczenie |
allow_remote_requests |
Zezwala klientom sieciowym na korzystanie z resolvera |
cache_max_ttl |
Maksymalny czas przechowywania odpowiedzi w cache |
max_concurrent_queries |
Limit równoległych zapytań DNS |
servers |
Lista serwerów DNS upstream |
dynamic_servers |
Serwery DNS pobierane dynamicznie (np. z DHCP ISP) |
comment |
Opis administracyjny |
2. Rola cache DNS
Mechanizm cache:
- znacząco redukuje liczbę zapytań wychodzących,
- poprawia wydajność sieci,
- zwiększa odporność na chwilowe awarie upstream.
W konfiguracji:
cache_max_ttl = "1d"
oznacza, że odpowiedzi mogą być przechowywane przez maksymalnie 24 godziny.
3. Serwery upstream
servers = ["1.1.1.1", "8.8.8.8"]
Oznacza to wykorzystanie:
- **Cloudflare DNS –
1.1.1.1,
- **Google DNS –
8.8.8.8.
Zastosowanie co najmniej dwóch niezależnych operatorów DNS zwiększa odporność na awarie.
Integracja DNS z DHCP
W projekcie iac-mikrotik DNS jest bezpośrednio powiązany z DHCP:
pve-s1.rachuna-net.pl → 10.3.0.11
10.3.0.11 → pve-s1.rachuna-net.pl
Dzięki temu:
- hosty są widoczne po nazwach,
- działa poprawnie Kerberos, LDAP, TLS, monitoring, HA Proxmox.
Zasady projektowe i dobre praktyki
1. Ogólne zasady
- Jeden centralny resolver DNS dla całej infrastruktury
- DNS zawsze wskazywany przez DHCP
- DNS zawsze działa na routerze brzegowym
- Brak konfiguracji DNS bezpośrednio na hostach
2. Bezpieczeństwo
-
allow_remote_requests powinien być:
- włączony tylko dla sieci zaufanych,
-
brak otwartego DNS do Internetu,
-
firewall powinien blokować:
- zapytania DNS spoza infrastruktury.
3. Spójność DNS i TLS
Typowe błędy i jak ich unikać
| Problem |
Przyczyna |
Rozwiązanie |
| DNS nie odpowiada |
allow_remote_requests = false |
Ustaw na true |
| Brak internetu mimo IP |
Brak upstream DNS |
Ustaw servers |
| Brak PTR |
Brak integracji z DHCP |
Używaj hostname w lease |
| Timeouty DNS |
Zbyt niski max_concurrent_queries |
Zwiększ limit |
Podsumowanie
Serwer DNS w iac-mikrotik zapewnia:
- centralny, cache’ujący resolver,
- dynamiczne rekordy A i PTR z DHCP,
- wysoką wydajność dzięki cache,
- pełną deklaratywność w IaC,
- brak ręcznej konfiguracji RouterOS,
- spójność nazw w całym środowisku IT.
Jeżeli chcesz, mogę dodatkowo przygotować:
- dokumentację rekordów statycznych DNS (A, CNAME, TXT),
- integrację DNS z Vault PKI,
- model DNS dla Proxmox + Kubernetes + Wi-Fi + DMZ,
- checklistę audytową DNS pod bezpieczeństwo.
3.1.4.4 - Rekord DNS

Konfiguracja Rekordów DNS
Oprócz działania jako resolver i cache, serwer DNS w RouterOS może również pełnić rolę lokalnego, autorytatywnego serwera rekordów statycznych dla domeny wewnętrznej.
W projekcie iac-mikrotik realizowane jest to poprzez mapę dns_records w module routeros-dns.
Rekordy te są:
- w pełni zarządzane przez IaC,
- wersjonowane w Git,
- niezależne od DHCP,
- odporne na restart routera,
- wykorzystywane przez TLS, monitoring, reverse proxy, klastry i routing.
Struktura dns_records
Rekordy DNS definiowane są jako mapa rekordów, gdzie:
- klucz mapy = identyfikator rekordu,
- wartość = pełna definicja wpisu DNS.
Przykład konfiguracji:
dns_records = {
"router.rachuna-net.pl" = {
name = "router.rachuna-net.pl"
address = "10.0.0.1"
type = "A"
ttl = "1w"
comment = "Router IP address"
}
}
Omówienie parametrów rekordu DNS
| Parametr |
Znaczenie techniczne |
name |
Pełna nazwa hosta (FQDN) |
address |
Adres IP powiązany z nazwą |
type |
Typ rekordu DNS (najczęściej A) |
ttl |
Czas życia rekordu w cache |
comment |
Opis administracyjny |
Obsługiwane typy rekordów (praktyczne zastosowanie)
| Typ |
Zastosowanie |
A |
Mapowanie nazwa → IPv4 |
AAAA |
Mapowanie nazwa → IPv6 |
CNAME |
Alias do innej nazwy |
TXT |
SPF, DKIM, weryfikacje |
MX |
Serwery poczty |
NS |
Delegacja stref |
Przykład rekordu aliasu:
"dns.rachuna-net.pl" = {
name = "dns.rachuna-net.pl"
address = "router.rachuna-net.pl"
type = "CNAME"
ttl = "1d"
comment = "Alias for router DNS"
}
Rola rekordów statycznych vs DHCP
| Źródło rekordu |
Przeznaczenie |
| DHCP (dynamiczne) |
Laptopy, VM, urządzenia tymczasowe |
dns_records (statyczne) |
Routery, load balancery, proxmoxy, serwery, usługi infrastrukturalne |
✅ Zasada infrastrukturalna:
Każdy element krytyczny infrastruktury powinien posiadać rekord statyczny, a nie tylko dynamiczny z DHCP.
TTL – znaczenie w praktyce
| TTL |
Zastosowanie |
1h |
Sieci testowe |
1d |
Standard produkcyjny |
1w |
Routery, klastry, infrastruktura krytyczna |
U Ciebie:
oznacza, że:
- cache DNS będzie przechowywał wpis nawet przez 7 dni,
- zmiany IP wymagają ręcznego odświeżenia cache,
- idealne dla infrastruktury stałej (router, core).
Powiązanie z TLS, monitoringiem i reverse proxy
Statyczne rekordy DNS są wykorzystywane bezpośrednio przez:
- certyfikaty TLS (Vault PKI, ACME),
- monitoring (Prometheus, Zabbix, Grafana),
- reverse proxy (Nginx, Traefik),
- klastry (Proxmox, Kubernetes).
Brak statycznego DNS powoduje:
- niestabilność certyfikatów,
- błędy monitoringu,
- problemy z HA i load balancingiem.
Typowe błędy i jak ich unikać
| Problem |
Przyczyna |
Rozwiązanie |
| Rekord nie działa |
Błędna nazwa w name |
Tylko FQDN |
| Brak rozwiązywania |
DNS nie jest ustawiony przez DHCP |
Sprawdź dns_server |
| Stara odpowiedź DNS |
Zbyt długi TTL |
Zmniejsz TTL i wyczyść cache |
| Konflikt nazwy |
Istnieje rekord dynamiczny |
Usuń dynamiczny lub zmień nazwę |
Podsumowanie sekcji dns_records
Sekcja dns_records w iac-mikrotik zapewnia:
- centralne, statyczne wpisy DNS,
- pełną kontrolę nad infrastrukturą nazw,
- powtarzalność wdrożeń,
- brak ręcznej edycji RouterOS,
- kompatybilność z TLS, DHCP, monitoringiem i proxy,
- spójność nazw w całym ekosystemie IT.
3.1.5 - Integracja z projektem gitlab

Integracja z projektem gitlab
Terraform State to mechanizm w Terraformie, który przechowuje aktualny stan zarządzanej infrastruktury. Jest to plik (domyślnie terraform.tfstate), w którym Terraform zapisuje informacje o zasobach, ich konfiguracji oraz zależnościach. Dzięki temu Terraform może:
- Śledzić zmiany – porównuje aktualną infrastrukturę ze skonfigurowaną w kodzie, identyfikując różnice.
- Optymalizować działania – wie, które zasoby wymagają zmiany, zamiast tworzyć je od nowa.
- Zarządzać zależnościami – rozumie, w jakiej kolejności tworzyć, aktualizować lub usuwać zasoby.
- Współdzielić stan – umożliwia pracę zespołową poprzez zdalne przechowywanie stanu w backendach takich jak S3, GitLab czy Terraform Cloud.
Zarządzanie stanem jest kluczowe, dlatego warto używać zdalnego backendu zamiast przechowywać terraform.tfstate lokalnie, szczególnie w środowiskach zespołowych.
⚠️ Nigdy umieszczaj terraform state w bezpośrednio w repozytorium kodu
terraform init \
-backend-config="address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}" \
-backend-config="lock_address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}/lock" \
-backend-config="unlock_address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}/lock" \
-backend-config="username=gitlab-ci-token" \
-backend-config="password=${CI_JOB_TOKEN}" \
-backend-config="lock_method=POST" \
-backend-config="unlock_method=DELETE" \
-backend-config="retry_wait_min=5"
dla OpenTofu
tofu init \
-backend-config="address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}" \
-backend-config="lock_address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}/lock" \
-backend-config="unlock_address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}/lock" \
-backend-config="username=gitlab-ci-token" \
-backend-config="password=${CI_JOB_TOKEN}" \
-backend-config="lock_method=POST" \
-backend-config="unlock_method=DELETE" \
-backend-config="retry_wait_min=5"
gdzie:
- CI_PROJECT_ID - id projektu w gitlab
- CI_SERVER_URL - serwer URL
- TF_STATE_NAME - nazwa instancji state

3.1.6 - Importowanie obiektów

Importowanie istniejących obiektów
tofu Import – Co to jest i do czego służy?
tofu import to polecenie w OpenTofu, które umożliwia wprowadzenie istniejących zasobów do stanu (state) OpenTofu, bez konieczności ich tworzenia od zera. Jest to przydatne, gdy mamy zasoby zarządzane ręcznie lub przez inne narzędzia i chcemy przejąć nad nimi kontrolę za pomocą OpenTofu.
Do czego służy OpenTofu import?
- Przejmowanie kontroli nad istniejącymi zasobami – jeśli masz już zasoby w chmurze (np. VM w AWS, projekt w GitLab, użytkowników w Azure), możesz je zaimportować do OpenTofu bez ich ponownego tworzenia.
- Unikanie usuwania i ponownego tworzenia zasobów – jeśli ręcznie utworzony zasób nie znajduje się w stanie OpenTofu, ale istnieje, można go dodać do
state, zamiast niszczyć i tworzyć od nowa.
- Migracja do OpenTofu – jeśli zarządzałeś zasobami ręcznie lub przy pomocy innego narzędzia (np. Ansible, CloudFormation), możesz je przenieść do OpenTofu.
Ograniczenia tofu import
- Nie importuje konfiguracji (
.tf) – dodaje zasoby tylko do state, ale nie generuje kodu. Konfigurację trzeba dodać ręcznie.
- Brak wsparcia dla całych modułów –
tofu import działa na poziomie pojedynczych zasobów, a nie całych modułów.
- Niektóre zasoby nie są wspierane – nie wszystkie dostawcy (
providers) umożliwiają import wszystkich typów zasobów.
Przykłady importowanie obiektów
importowanie grupy gitlab
import {
to = module.pl_rachuna-net.module.infrastructure.module.opentofu.module.group_modules.gitlab_group.group
id = "100726684"
}
albo
tofu import module.pl_rachuna-net.module.infrastructure.module.opentofu.module.group_modules.gitlab_group.group 100726684
importowanie projektu gitlab
import {
to = module.pl_rachuna-net.module.infrastructure.module.opentofu.module.modules.module.gitlab_group.gitlab_project.project
id = "66189322"
}
albo
tofu import module.pl_rachuna-net.module.infrastructure.module.opentofu.module.modules.module.gitlab_group.gitlab_project.project 66189322
3.1.7 - Nadpisanie teraform states

Wysłanie opentofu state do gitlab
Push teraform state
Terraform GitLab States pozwala na zarządzanie i synchronizację stanu infrastruktury bezpośrednio w ramach projektu GitLab. Dzięki temu możliwe jest centralne przechowywanie i kontrola stanu, co ułatwia współpracę zespołową oraz automatyzację procesów CI/CD. W niniejszym dokumencie przedstawiono sposób wysyłania zmian do istniejącego stanu OpenTofu do GitLab za pomocą API.
#!/bin/env bash
curl --request POST \
--header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
--header "Content-Type: application/json" \
--data-binary "@default.json" \
"https://gitlab.com/api/v4/projects/${PRROJECT_ID}/terraform/state/${TF_STATE_NAME}"
3.2 - Packer

VM Template dla ProxMox
Packer to narzędzie do automatycznego budowania, instalacji systemu operacyjnego, konfiguracji jego według zdefiniowanych reguł i zapisania wyniku jako gotowy obraz do użycia.
Zamiast instalować system ręcznie, Packer wykonuje cały proces automatycznie: uruchamia maszynę, instaluje system operacyjny, konfiguruje go według zdefiniowanych reguł i zapisuje wynik jako gotowy obraz. Dzięki temu każdy wygenerowany template jest identyczny i możliwy do odtworzenia w dowolnym momencie.
Projekty Packer
| projekt |
version |
description |
| alma |
 |
Template Alma dla Proxmox generowany przez Packer |
| alpine |
 |
Template Alpine dla Proxmox generowany przez Packer |
| ubuntu |
 |
Template Ubuntu dla Proxmox generowany przez Packer |
Instalacja szablonów
Konfiguracja w Vault
pl.rachuna-net/infrastructure/packer
{
"SSH_PASSWORD": "techuser",
"SSH_PUBLIC_KEY": "ssh-...",
"SSH_USERNAME": "techuser"
}
pl.rachuna-net/auth/proxmox
{
"DEFAULT_NODE": "pve-s1",
"PASSWORD": "...",
"USERNAME": "root@pam"
}
Skrypt instalacyjny
#!/usr/bin/env bash
### VAULT CONNECTION ###
export VAULT_TOKEN="hvs....."
export VAULT_ADDR="https://vault.rachuna-net.pl"
direnv allow
packer init .
for file in $(find pkrvars -type f -name "*.hcl"); do
# Create a new vm template
packer fmt -var-file=$file .
packer validate -var-file=$file .
packer build -var-file=$file .
done
3.3 - Ansible

IaC za pomocą Ansible
Opentofu to narzędzie typu Infrastructure as Code (IaC), które umożliwia definiowanie, provisionowanie i zarządzanie infrastrukturą za pomocą plików konfiguracyjnych. Dzięki temu narzędziu możesz w sposób deklaratywny opisywać zasoby, takie jak serwery, sieci czy usługi w chmurze, a następnie automatycznie je tworzyć, modyfikować i usuwać, zapewniając spójność środowisk.
Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.
Poniżej znajduje się lista projektów Infrastructure as a Code.
| project |
version |
description |
| iac-gitlab |
 |
IAC do zarządzania środowiskiem GitLab. |
| iac-vault |
 |
IAC do zarządzania Vault. |
Architektura projektu OpenTofu w pl.rachuna-net
# Przykładowy opis struktury projektu
pl.rachuna-net/infrastructure/opentofu
├── gitlab-profile # Documentation
├── home.rachuna-net.pl
├── iac-gitlab
├── iac-vault
├── modules # Opentofu modules
│ ├── gitlab-group # Opentofu module for menagment groups
│ ├── gitlab-project # Opentofu module for menagment projects
│ ├── proxmox-container
│ ├── proxmox-download-container
│ ├── proxmox-vm
│ ├── routeros-bonding
│ ├── routeros-bridge
│ ├── routeros-dhcp-server
│ ├── routeros-dns
│ ├── routeros-ethernet
│ ├── routeros-system
│ ├── routeros-vlan
│ ├── vault-pki-cert-ca
│ └── vault-pki-cert-intermediate
├── proxmox
└── router.rachuna-net.pl
4 - Usługi

Usługi
📍 Infrastructure as Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
Założenia projektów Infrastructure as a Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym:
- zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
- automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.
Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.
4.1 - Gitlab

Giatlab
📍 Infrastructure as Code
GitLab CE (Community Edition) to otwarto-źródłowa wersja GitLaba – kompletnej platformy DevOps, która łączy w sobie repozytoria Git, zarządzanie projektami, CI/CD oraz narzędzia do monitoringu i bezpieczeństwa. W przeciwieństwie do wersji komercyjnych GitLab EE, edycja CE jest w pełni darmowa i rozwijana we współpracy ze społecznością.
Dzięki GitLab CE możesz w jednym miejscu:
- hostować własne repozytoria Git,
- planować zadania i zarządzać issue,
- budować, testować i wdrażać aplikacje przez wbudowane CI/CD,
- pracować w modelu DevOps bez dodatkowych narzędzi.
To świetny wybór dla firm i zespołów, które chcą pełną kontrolę nad swoim środowiskiem, bezpieczeństwem i procesami — bez licencji i vendor lock-in.
✅ 1. Wgraj swój certyfikat i klucz do GitLaba
GitLab (omnibus) oczekuje certów w:
/etc/gitlab/ssl/
Utwórz katalog i wrzuć tam swoje pliki:
sudo mkdir -p /etc/gitlab/ssl
sudo chmod 700 /etc/gitlab/ssl
Załóżmy, że masz:
- certyfikat:
gitlab.rachuna-net.pl.crt
- klucz prywatny:
gitlab.rachuna-net.pl.key
- (opcjonalnie) certyfikat CA:
ca.crt
Skopiuj je:
sudo cp gitlab.rachuna-net.pl.crt /etc/gitlab/ssl/
sudo cp gitlab.rachuna-net.pl.key /etc/gitlab/ssl/
sudo cp ca.crt /etc/gitlab/ssl/ # jeśli potrzebne
⚠️ Nazwy plików muszą odpowiadać domenie z external_url!
Czyli jeśli używasz:
external_url "https://gitlab.rachuna-net.pl"
to pliki muszą mieć nazwę:
/etc/gitlab/ssl/gitlab.rachuna-net.pl.crt
/etc/gitlab/ssl/gitlab.rachuna-net.pl.key
Daj im właściwe prawa:
sudo chmod 600 /etc/gitlab/ssl/*
✅ 2. Edytuj /etc/gitlab/gitlab.rb
Otwórz:
sudo nano /etc/gitlab/gitlab.rb
Ustaw:
external_url "https://gitlab.rachuna-net.pl"
nginx['enable'] = true
# nginx['client_max_body_size'] = '0'
nginx['redirect_http_to_https'] = true
# nginx['redirect_http_to_https_port'] = 80
##! Most root CA's are included by default
nginx['ssl_client_certificate'] = "/etc/gitlab/ssl/ca.crt"
##! enable/disable 2-way SSL client authentication
# nginx['ssl_verify_client'] = "off"
##! if ssl_verify_client on, verification depth in the client certificates chain
# nginx['ssl_verify_depth'] = "1"
nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.rachuna-net.pl.crt"
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.rachuna-net.pl.key"
WAŻNE:
- Jeśli certyfikat zawiera pełny chain (cert + intermediate), nie musisz używać
ssl_certificate_chain.
- Jeśli masz oddzielne pliki, musisz go podać.
✅ 3. Przeładuj konfigurację GitLaba
sudo gitlab-ctl reconfigure
Sprawdź status:
✅ 4. Jeżeli masz własne CA — dodaj CA do systemu
Jeżeli certyfikat jest podpisany przez Twoje prywatne CA (Vault/MikroTik/Proxmox/etc.), to na serwerze oraz komputerach klientów musisz dodać CA.
Na samym GitLabie:
sudo cp ca.crt /usr/local/share/ca-certificates/my-ca.crt
sudo update-ca-certificates
🔍 5. Test z poziomu kontenera
curl -I https://gitlab.rachuna-net.pl
Jeśli dostaniesz 200/302 i brak błędów certyfikatu → cert działa.
🟢 6. Gotowe — GitLab działa po HTTPS z Twoim certem
Możesz wejść w:
https://gitlab.rachuna-net.pl
Jeśli chcesz, mogę:
✓ sprawdzić Twoje pliki certów (jak je wgrałeś),
✓ przygotować pełny gitlab.rb pod Twoją infrastrukturę,
✓ pomóc skonfigurować ingress/reverse proxy albo HSTS.
Daj znać, co chcesz zrobić dalej.
4.1.1 - Instalacja gitlab-ce

Instalacja gitlab-ce
Wymagania:
- Skonfigurowana domena
gitlab.rachuna-net.pl
- Skonfigurowana domena
registry.rachuna-net.pl
- Skonfigurowana domena
pages.rachuna-net.pl
- certyfikaty ssl
Przygotowanie środowiska
# sprawdzenie czy serwer korzysta z systemd
systemctl is-system-running
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl openssh-server postfix tzdata perl
# dodanie repozytorium gitlab
curl "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh" | sudo bash
# instalacja gitlab-ce
sudo apt install -y gitlab-ce
Konfiguracja certyfikatów SSL
4.2 - Vault

Vault
📍 Infrastructure as Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
Założenia projektów Infrastructure as a Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym:
- zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
- automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.
Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.
5 - Procesy

Procesy
📍 Infrastructure as Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
Założenia projektów Infrastructure as a Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym:
- zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
- automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.
Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.
5.1 - Utworzenie nowego repozytorium

Utworzenie nowego repozytorium
W repozytorium: iac-gitlab-com
Wymagania
- Znajomość opentofu/terraform
- Znajomość git
gitGraph
commit tag: "v1.0.0"
commit tag: "v1.1.0"
branch feature
checkout feature
commit id: "feat: Utworzenie nowego repozytorium A"
commit id: "feat: Utworzenie nowego repozytorium B"
checkout main
merge feature tag: "v1.2.0"
commit tag: "v1.3.0"
commit tag: "v1.4.0"
Utworzenie zmiany (feature)
module "install-gitlab" {
source = "git@gitlab.rachuna-net.pl:pl.rachuna-net/infrastructure/opentofu/modules/gitlab-project.git?ref=v1.1.0"
name = "install-gitlab"
description = "IAC do zarządzania środowiskiem Gitlab."
visibility = "public"
avatar = "gitlab"
parent_group = local.parent_name
project_type = local.project_type
}
Merge Request do main

Akceptacja zmian - wdrożenie

5.2 - Utworzenie nowego ct

Utworzenie nowego ct
📍 Infrastructure as Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
Założenia projektów Infrastructure as a Code
Infrastructure as Code (IaC) to podejście do zarządzania infrastrukturą IT, w którym:
- zasoby są definiowane i utrzymywane za pomocą kodu, a nie manualnych operacji.
- automatyczne tworzenie, aktualizowanie oraz usuwanie zasobów w chmurze i środowiskach lokalnych, na podstawie deklaratywnych plików konfiguracyjnych.
Wdrażając podejście IaC z użyciem OpenTofu, należy przyjąć szereg kluczowych założeń projektowych, które zapewniają bezpieczeństwo, skalowalność oraz powtarzalność środowisk infrastrukturalnych.