Environment_Infrastructure/facts/prod-kurulum-gecmisi.md
Murat ÖZDEMİR c568e31515 Finalize production database bootstrap automation
Add DB-specific StorageBox ownership variables and make the davfs mount role honor configurable uid and gid values so database containers can access mounted files.

Extend the prod DB node role to sync StorageBox writes, generate and distribute the MongoDB replica set keyfile, wait for the keyfile on each node, and enforce keyfile permissions.

Tune MongoDB and Patroni templates for quieter logging, correct secret variable names, local bootstrap trust, and production network pg_hba coverage.

Refresh the production setup history with the current bootstrap sequence, DB stack deployment workflow, MongoDB replica set initialization, Patroni validation, and completed DB cluster status.
2026-05-21 21:48:11 +03:00

178 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Prod Ortamı Kurulum Geçmişi
Prod kurulum adımları ve mevcut yapı.
## Terraform
### Hetzner Cloud Yapılandırması
Test ve prod ayrı Hetzner Cloud projelerinde çalışır; her proje için ayrı API token kullanılır. `terraform/hetzner/prod/terraform.tfvars` içindeki `hcloud_token` değeri `iklim_prod` projesinin token'ına aittir.
Prod sunucuları `lifecycle { prevent_destroy = true }` ile korunur.
### 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
### Yapılandırma Notları
`group_vars/all/vars.yml` içindeki `admin_allowed_cidrs` tüm admin IP'lerini boşlukla ayrılmış string olarak içerir ve Terraform `terraform.tfvars` ile birebir uyumludur:
```yaml
admin_allowed_cidrs: "78.187.87.109/32 95.70.151.248/32"
admin_ssh_public_key_path: "~/.ssh/id_rsa.pub"
```
Hardening rolü `PermitRootLogin prohibit-password` uygular — key tabanlı root girişi açık, parola ile root girişi kapalıdır.
`vault_iklim_password` per-host `host_vars/<hostname>/vault.yml` dosyalarında tanımlıdır, her sunucu farklı şifreye sahiptir:
```text
prod/
host_vars/
iklim-app-01/vault.yml
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
```
### StorageBox Mount
StorageBox WebDAV mount (`/mnt/storagebox`) davfs2 ile yapılır. DB node'larında `uid=999,gid=999` parametreleriyle mount edilir (PostgreSQL/MongoDB container uid'i ile uyumlu). `group_vars/db/vars.yml` içinde tanımlanır:
```yaml
storagebox_uid: "999"
storagebox_gid: "999"
```
### Bootstrap Çalıştırma Sırası
```bash
cd Environment_Infrastructure/ansible/prod
# 1. Tüm node'lar — base, hardening, docker, dizinler, storagebox
ansible-playbook prod-bootstrap.yml \
--tags base,hardening,docker,node_dirs,storagebox,storagebox_ssh_key \
--vault-password-file=../.vault_pass
# 2. Swarm kurulumu
ansible-playbook prod-bootstrap.yml \
--tags swarm \
--vault-password-file=../.vault_pass
# 3. DB node label'ları
ansible-playbook prod-bootstrap.yml \
--tags db_labels \
--vault-password-file=../.vault_pass
# 4. DB node konfigürasyonu (StorageBox dizinleri, patroni.yml, mongod.conf, keyfile)
ansible-playbook prod-bootstrap.yml \
--tags db_stack \
--limit db \
--vault-password-file=../.vault_pass
# 5. Act runner kurulumu
ansible-playbook prod-bootstrap.yml \
--tags act_runner \
--vault-password-file=../.vault_pass
```
## DB Stack Deploy
### Custom Image Build
`build/patroni-postgis/` altında PostGIS + Patroni imajı bulunur (`registry.tarla.io/iklimco/custom-patroni-postgis:18-3.6`). `ops/push-harbor-custom-images.sh` ile Harbor'a push edilir.
### Stack Deploy
```bash
# Lokal → app-01
scp ./docker-stack-* root@178.104.210.41:/home/iklim/
# app-01'de
cd /home/iklim
# password; 'https://passwords.tarla.io' içinde "tarla.io[Hetzner] Utils Server" klasörünün altında
scp -P 23 u469968@u469968.your-storagebox.de:prod/secrets/iklim.co/.env.secrets.shared \
/tmp/.env.secrets.shared
chmod 600 /tmp/.env.secrets.shared
scp -P 23 u469968@u469968.your-storagebox.de:prod/secrets/iklim.co/.env.secrets \
/tmp/.env
chmod 600 /tmp/.env
export $(grep -v '^\s*#' /tmp/.env.secrets.shared | grep -v '^\s*$' | xargs)
export $(grep -v '^\s*#' /tmp/.env | grep -v '^\s*$' | xargs)
docker stack deploy --with-registry-auth -c docker-stack-db.prod.yml iklim-db
# deploy başarılı bir şekilde tamamlanınca
rm /tmp/.env
rm /tmp/.env.secrets.shared
history -c && history -w
```
### MongoDB Replica Set Init
```bash
ssh root@<db-01-ip>
# password; 'https://passwords.tarla.io' içinde "tarla.io[Hetzner] Utils Server" klasörünün altında
scp -P 23 u469968@u469968.your-storagebox.de:prod/secrets/iklim.co/.env.secrets.shared \
/tmp/.env.secrets.shared
chmod 600 /tmp/.env.secrets.shared
scp -P 23 u469968@u469968.your-storagebox.de:prod/secrets/iklim.co/.env.secrets \
/tmp/.env
chmod 600 /tmp/.env
export $(grep -v '^\s*#' /tmp/.env.secrets.shared | grep -v '^\s*$' | xargs)
export $(grep -v '^\s*#' /tmp/.env | grep -v '^\s*$' | xargs)
MONGO_CID=$(docker ps --filter name=iklim-db_mongodb-01 --format "{{.ID}}" | head -1)
docker exec -it $MONGO_CID mongosh \
-u "$DATABASE_MONGODB_ROOT_USER" \
-p "$DATABASE_MONGODB_ROOT_PASSWD" \
--authenticationDatabase admin --eval '
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongodb-01:27017" },
{ _id: 1, host: "mongodb-02:27017" },
{ _id: 2, host: "mongodb-03:27017" }
]
})'
rm /tmp/.env
rm /tmp/.env.secrets.shared
history -c && history -w
```
### Patroni Cluster Doğrulama
```bash
# app-01'den
curl -s http://10.20.20.11:8008/cluster | python3 -m json.tool
```
## Mevcut Durum (2026-05-21)
| 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 | ✅ |
| Ansible db_stack (StorageBox DB dizinleri + config) | ✅ |
| Ansible act_runner (3 prod runner Gitea'da Idle) | ✅ |
| DB stack deploy (etcd + MongoDB + Patroni) | ✅ |
| MongoDB replica set init (rs0: 1 primary, 2 secondary) | ✅ |
| Patroni HA cluster (1 leader, 2 replica, lag=0) | ✅ |
| Ana infra stack deploy (docker-stack-infra.prod.yml) | ⏳ bekliyor |
| Deploy pipeline ilk çalışma | ⏳ bekliyor |