# Prod Ortamı Kurulum Geçmişi İlk prod kurulumunda yaşanan sorunlar, uygulanan düzeltmeler ve mevcut durum. ## Terraform ### Ayrı Hetzner Projesi Zorunluluğu Test ve prod ayrı Hetzner Cloud projelerinde çalışır. Her proje için ayrı API token alınmalıdır. Aynı token kullanılırsa `terraform apply` sırasında SSH key çakışması hatası alınır: ``` SSH key not unique (uniqueness_error, ) ``` Hetzner Cloud, aynı public key'i bir projede yalnızca bir kez kabul eder. Test projesinde oluşturulmuş key, prod projesine ait olmayan bir token ile kullanılamaz. **Düzeltme:** `terraform/hetzner/prod/terraform.tfvars` içindeki `hcloud_token` değeri `iklim_prod` projesinin token'ı olmalıdır. ### State Kaybı Sonrası SSH Key Import Terraform state'i olmadan `terraform apply` çalıştırılırsa, Hetzner'da zaten var olan SSH key yeniden oluşturulmaya çalışılır ve yukarıdaki hata alınır. Bu durumda key Hetzner Console → Security → SSH Keys üzerinden ID'si bulunarak import edilir: ```bash terraform import hcloud_ssh_key.admin ``` ### prevent_destroy Prod sunucuları `lifecycle { prevent_destroy = true }` ile korunur. `terraform destroy` çalıştırmak gerekirse bu değer geçici olarak `false` yapılır, işlem bittikten sonra tekrar `true`'ya alınır. ### Inventory Üretimi ```bash cd Environment_Infrastructure/terraform/hetzner/prod mkdir -p ../../../ansible/prod/inventory/generated terraform output -raw ansible_inventory_yaml > ../../../ansible/prod/inventory/generated/prod.yml ``` ## Ansible ### admin_allowed_cidrs `group_vars/all/vars.yml` içindeki `admin_allowed_cidrs` değeri başlangıçta `127.0.0.1/8` olarak tanımlanmıştı. Bu değer hardening rolü tarafından firewalld'a uygulanır ve SSH erişimini tamamen kapatır. Doğru değer: tüm admin IP'lerini boşlukla ayrılmış string olarak içermelidir. ```yaml admin_allowed_cidrs: "78.187.87.109/32 95.70.151.248/32" ``` Terraform `terraform.tfvars` içindeki `admin_allowed_cidrs` ile birebir uyumlu olmalıdır. ### admin_ssh_public_key_path `group_vars/all/vars.yml` içinde başlangıçta `~/.ssh/id_ed25519.pub` yazıyordu; bu makinede bu dosya yoktu. Doğru değer: ```yaml admin_ssh_public_key_path: "~/.ssh/id_rsa.pub" ``` ### PermitRootLogin Hardening rolü başlangıçta `PermitRootLogin no` uyguluyordu. Bu ayar sshd handler'ı ilk play'in sonunda tetiklediğinden, aynı Ansible çalışmasının devamındaki play'ler (swarm, db_labels, db_stack, act_runner) root ile bağlanamıyordu. **Düzeltme:** `PermitRootLogin prohibit-password` olarak değiştirildi. Key tabanlı root girişi açık kalır; parola ile root girişi engellenir. Ansible tüm bootstrap boyunca root ile bağlanmaya devam edebilir. ### vault_iklim_password — Per-Host Şifre `vault_iklim_password` başlangıçta `group_vars/all/vault.yml` içinde tek bir değer olarak tanımlıydı; tüm sunuculara aynı şifre uygulanıyordu. Her sunucuya farklı şifre vermek için `host_vars//vault.yml` yapısına geçildi: ```text prod/ group_vars/all/vault.yml ← vault_iklim_password KALDIRILDI host_vars/ iklim-app-01/vault.yml ← vault_iklim_password: "<şifre>" iklim-app-02/vault.yml iklim-app-03/vault.yml iklim-db-01/vault.yml iklim-db-02/vault.yml iklim-db-03/vault.yml ``` Her dosya ayrı ayrı şifrelenir: `ansible-vault encrypt host_vars//vault.yml` ### StorageBox Mount StorageBox WebDAV mount (`/mnt/storagebox`) davfs2 ile yapılır. Aynı anda 6 sunucunun mount denemesi zaman zaman sorun çıkarabilir; Ansible idempotent çalıştığından tekrar çalıştırmak yeterlidir. ### Bootstrap Çalıştırma Sırası ```bash cd Environment_Infrastructure/ansible/prod # 1. Tüm node'lar ansible-playbook prod-bootstrap.yml \ --tags base,hardening,docker,node_dirs,storagebox,storagebox_ssh_key \ --ask-vault-pass # 2. Swarm kurulumu ansible-playbook prod-bootstrap.yml \ --tags swarm \ --ask-vault-pass # 3. DB node label'ları ansible-playbook prod-bootstrap.yml \ --tags db_labels \ --ask-vault-pass # 4. DB node konfigürasyonu ansible-playbook prod-bootstrap.yml \ --tags db_stack \ --ask-vault-pass # 5. Act runner kurulumu ansible-playbook prod-bootstrap.yml \ --tags act_runner \ --ask-vault-pass ``` ## Mevcut Durum (2026-05-19) | Adım | Durum | | --- | --- | | Terraform — 6 sunucu, ağ, firewall, floating IP | ✅ | | Ansible base + hardening + docker + node_dirs | ✅ | | Ansible storagebox + storagebox_ssh_key | ✅ | | Ansible swarm (3 manager app + 3 worker db) | ✅ | | Ansible db_labels (Patroni koordinasyonu için) | ✅ | | Ansible db_stack (StorageBox DB dizinleri) | ✅ | | Ansible act_runner (3 prod runner Gitea'da Idle) | ✅ | | DB stack deploy (docker-stack-db.prod.yml) | ⏳ bekliyor | | MongoDB replica set init | ⏳ bekliyor | | Ana infra stack deploy (docker-stack-infra.prod.yml) | ⏳ bekliyor | | Deploy pipeline ilk çalışma | ⏳ bekliyor |