- This commit introduces the Terraform configuration to provision a production environment on Hetzner Cloud, building on the existing test setup. - Key improvements and new features include: * **Multi-node clusters:** Scaling to 3-node Swarm application and database clusters for improved resilience. * **High availability:** Utilizing a Hetzner Floating IP for the application entry point and `spread` placement groups for fault tolerance across physical hosts. * **Enhanced network security:** Internal management services (RabbitMQ, APISIX, Prometheus, Grafana) are restricted to the application subnet, expected to be accessed via an internal reverse proxy (SWAG). * **Internal database replication:** New firewall rules enable PostgreSQL replication and MongoDB replica set traffic within the database subnet. * **Refined test environment:** Updates to align `test` configuration with the new `prod` structure, including a dedicated floating IP and adjusted firewall rules. * **Configuration standardization:** Environment-specific details moved to `locals.tf` for clarity, with upgraded server types and migration to Rocky Linux as the base image. - Updates were also made to the latest version of Terraform to ensure consistency in the documentation
6.0 KiB
01 - Test Terraform IaC
Bu asamanin amaci test Hetzner Cloud Project icinde minimum IaaS kaynaklarini Terraform ile olusturmaktir. Bu dokuman tek basina uygulanabilir olacak sekilde yazilmistir.
Kapsam
Terraform test ortaminda sunlari olusturur:
- Private network:
iklim-test-net - Subnetler:
- App/Swarm subnet:
10.10.10.0/24 - DB subnet:
10.10.20.0/24
- App/Swarm subnet:
- Firewall:
- Public ingress: sadece
22/tcp,80/tcp,443/tcp - Private ingress:
07-private-network-port-matrisi.mddosyasindaki test kurallari
- Public ingress: sadece
- SSH key
- Placement group:
iklim-test-spread - Floating IP: swarm entry point icin sabit IPv4
- Server:
iklim-app-01iklim-db-01
- Ansible inventory output
Terraform DB yazilimini kurmaz. DB node sadece makine, network ve firewall seviyesinde hazirlanir.
Onerilen Dosya Yapisi
terraform/
hetzner/
test/
versions.tf
providers.tf
variables.tf
locals.tf
network.tf
firewall.tf
placement.tf
servers.tf
outputs.tf
terraform.tfvars.example
terraform.tfvars commit edilmeyecek. .gitignore icinde ignore edilmelidir.
Degiskenler
Minimum degiskenler:
hcloud_token = "secret"
location = "fsn1"
image = "rocky-10"
server_type_swarm = "cx32"
server_type_db = "cx42"
admin_ssh_public_key_path = "~/.ssh/id_ed25519.pub"
admin_allowed_cidrs = ["X.X.X.X/32"]
environment sabiti locals.tf icindedir; tfvars ile override edilmez.
location icin tek lokasyonla baslanir. Farkli region/lokasyon felaket kurtarma bu asamada konu disidir; ileride dokumana eklenmelidir.
Server Rolleri
| Server | Private IP | Rol |
|---|---|---|
iklim-app-01 |
10.10.10.11 |
Swarm manager + app worker + Gitea runner |
iklim-db-01 |
10.10.20.11 |
Manuel DB kurulumu icin hazir DB node |
Private IP'ler Terraform icinde sabit tanimlanmalidir. Ansible inventory ve firewall kurallari deterministik kalir.
Firewall Kurallari
Public ingress:
| Port | Kaynak | Hedef |
|---|---|---|
22/tcp |
admin_allowed_cidrs |
Tum test node'lari |
80/tcp |
0.0.0.0/0, ::/0 |
iklim-app-01 |
443/tcp |
0.0.0.0/0, ::/0 |
iklim-app-01 |
Public ingress icin 8200/tcp, 5432/tcp, 27017/tcp, 5672/tcp, 15672/tcp, 6379/tcp, 2379/tcp, 9000/tcp, 9180/tcp, 9090/tcp, 3000/tcp acilmayacak.
Private ingress (app subnet 10.10.10.0/24 kaynakli):
| Port | Servis | Erisim yontemi |
|---|---|---|
15672/tcp |
RabbitMQ Management | SWAG arkasinda 443 — IP kisitli |
9090/tcp |
Prometheus | SWAG arkasinda 443 — IP kisitli |
3000/tcp |
Grafana | SWAG arkasinda 443 — IP kisitli |
9000/tcp |
APISIX Dashboard | SWAG arkasinda 443 — IP kisitli |
9180/tcp |
APISIX Admin API | Docker overlay icinden sadece Dashboard erisir; insan erisimi gerekmez |
8200/tcp |
Vault | Docker overlay / private network |
IP kisitlamasi Hetzner firewall'da degil, SWAG nginx konfigurasyonunda yapilir.
Bu portlarin hicbiri admin_allowed_cidrs kaynagiyla public'ten acilmaz.
Diger private ingress kurallari icin 07-private-network-port-matrisi.md kaynak alinacak.
Placement Group
iklim-test-spread placement group type = "spread" olacak. Testte iki server oldugu icin bu grup iklim-app-01 ve iklim-db-01 makinelerinin farkli fiziksel host'lara dagitilmasini hedefler.
Not: Spread placement group farkli kabinet veya lokasyon garantisi degildir; tek fiziksel host arizasinin etkisini azaltir.
Terraform Cikti Beklentisi
outputs.tf minimum su bilgileri uretmelidir:
output "ansible_inventory_yaml" {
sensitive = false
}
output "test_private_ips" {
sensitive = false
}
output "test_public_ips" {
sensitive = false
}
Inventory output'u daha sonra ansible/inventory/generated/test.yml dosyasina yazilabilir. Inventory dosyasinda secret bulunmayacaksa commit edilebilir; secret veya token icerirse commit edilmeyecek.
Lifecycle ve Resize Politikasi
server_type Degisikligi (Yeniden Boyutlandirma)
server_type degistirmek Terraform destroy+create tetiklemez. hcloud provider
bunu natively destekler: sunucuyu durdurur, Hetzner Resize API'sini cagirir,
yeniden baslatir. terraform.tfvars icinde degeri guncelle, terraform apply calistir.
Downtime olur (sunucu durur ve baslar) ancak disk, kurulu yazilim ve Docker volumes
korunur. ignore_changes veya manuel adim gerekmez.
Hangi Degisiklikler Sunucuyu Zorla Yeniden Olusturur?
| Degisen alan | Davranis | Not |
|---|---|---|
server_type |
In-place resize (provider native) | terraform apply yeterli |
hcloud_server_network |
Sadece attachment guncellenir | Ayri resource kullanildigi icin |
hcloud_firewall_attachment |
Sadece attachment guncellenir | Ayri resource kullanildigi icin |
placement_group_id |
Hetzner API degisime izin vermiyor → destroy+create | Degistirme |
image |
Disk imaji degisir → destroy+create | Degistirme |
location |
Baska datacenter'a tasinamaz → destroy+create | Degistirme |
Network ve Firewall Attachment Ayrimi
network blogu ve firewall_ids hcloud_server icine gomulmez. Bunun yerine
ayri resource tanimlanir:
hcloud_server_network— private IP atamasihcloud_firewall_attachment— firewall iliskisi
Gomulu tanimlamada bazi provider versiyonlari bu alanlardaki degisiklikleri sunucu recreation olarak yorumlar. Ayri resource kullanildiginda sadece attachment guncellenir, sunucu dokunulmaz.
prevent_destroy Korumasi
Her sunucuya lifecycle { prevent_destroy = true } eklenir. Bu blok varken
Terraform hicbir kosulda sunucuyu silemez, plan asamasinda hata verir.
Kasitli silmek icin once lifecycle blogunu gecici olarak kaldir.
Kabul Kriterleri
terraform plansadece test Hetzner Project token'i ile calisir.terraform applysonrasinda 2 server olusur.- Iki server private network uzerinden birbirine erisebilir.
- Public internetten sadece
22,80,443firewall seviyesinde aciktir. - Vault
8200public'ten kapali kalir. - Terraform state repo'ya commit edilmez.