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.
This commit is contained in:
parent
e3787d80f6
commit
c568e31515
4
ansible/prod/group_vars/db/vars.yml
Normal file
4
ansible/prod/group_vars/db/vars.yml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# DB node'larında StorageBox uid/gid=999 (mongodb ve postgres container user)
|
||||||
|
# davfs2 dosyaları uid 999 sahibi gösterir; container içi erişim açılır.
|
||||||
|
storagebox_uid: "999"
|
||||||
|
storagebox_gid: "999"
|
||||||
@ -11,6 +11,9 @@
|
|||||||
state: directory
|
state: directory
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Sync StorageBox after directory creation
|
||||||
|
ansible.builtin.command: sync
|
||||||
|
|
||||||
- name: Deploy mongod.conf to StorageBox
|
- name: Deploy mongod.conf to StorageBox
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: mongod.conf.j2
|
src: mongod.conf.j2
|
||||||
@ -22,3 +25,30 @@
|
|||||||
src: patroni.yml.j2
|
src: patroni.yml.j2
|
||||||
dest: "{{ storagebox_mount_point }}/db/postgresql-{{ inventory_hostname.split('-')[-1] }}/config/patroni.yml"
|
dest: "{{ storagebox_mount_point }}/db/postgresql-{{ inventory_hostname.split('-')[-1] }}/config/patroni.yml"
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Sync StorageBox after config file writes
|
||||||
|
ansible.builtin.command: sync
|
||||||
|
|
||||||
|
- name: Generate MongoDB replica set keyfile on db-01
|
||||||
|
when: inventory_hostname == 'iklim-db-01'
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
openssl rand -base64 756 > {{ storagebox_mount_point }}/db/mongodb-01/config/rs-auth.key
|
||||||
|
chmod 400 {{ storagebox_mount_point }}/db/mongodb-01/config/rs-auth.key
|
||||||
|
cp {{ storagebox_mount_point }}/db/mongodb-01/config/rs-auth.key \
|
||||||
|
{{ storagebox_mount_point }}/db/mongodb-02/config/rs-auth.key
|
||||||
|
cp {{ storagebox_mount_point }}/db/mongodb-01/config/rs-auth.key \
|
||||||
|
{{ storagebox_mount_point }}/db/mongodb-03/config/rs-auth.key
|
||||||
|
chmod 400 {{ storagebox_mount_point }}/db/mongodb-02/config/rs-auth.key
|
||||||
|
chmod 400 {{ storagebox_mount_point }}/db/mongodb-03/config/rs-auth.key
|
||||||
|
sync
|
||||||
|
args:
|
||||||
|
creates: "{{ storagebox_mount_point }}/db/mongodb-01/config/rs-auth.key"
|
||||||
|
|
||||||
|
- name: Wait for MongoDB keyfile on this node's StorageBox mount
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
path: "{{ storagebox_mount_point }}/db/mongodb-{{ inventory_hostname.split('-')[-1] }}/config/rs-auth.key"
|
||||||
|
timeout: 60
|
||||||
|
|
||||||
|
- name: Fix MongoDB keyfile permissions on this node
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
chmod 400 {{ storagebox_mount_point }}/db/mongodb-{{ inventory_hostname.split('-')[-1] }}/config/rs-auth.key
|
||||||
|
|||||||
@ -4,13 +4,9 @@ storage:
|
|||||||
engine: "wiredTiger"
|
engine: "wiredTiger"
|
||||||
dbPath: "/data/db"
|
dbPath: "/data/db"
|
||||||
directoryPerDB: true
|
directoryPerDB: true
|
||||||
systemLog:
|
wiredTiger:
|
||||||
verbosity: 0
|
engineConfig:
|
||||||
timeStampFormat: "iso8601-local"
|
configString: "verbose=[]"
|
||||||
destination: file
|
|
||||||
path: "/data/log/mongo.log"
|
|
||||||
logAppend: true
|
|
||||||
logRotate: rename
|
|
||||||
replication:
|
replication:
|
||||||
replSetName: "{{ mongodb_replset_name }}"
|
replSetName: "{{ mongodb_replset_name }}"
|
||||||
security:
|
security:
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
log:
|
||||||
|
level: WARNING
|
||||||
|
|
||||||
scope: iklim-postgres
|
scope: iklim-postgres
|
||||||
namespace: /db/
|
namespace: /db/
|
||||||
name: postgresql-{{ inventory_hostname.split('-')[-1] }}
|
name: postgresql-{{ inventory_hostname.split('-')[-1] }}
|
||||||
@ -34,13 +37,19 @@ bootstrap:
|
|||||||
- data-checksums
|
- data-checksums
|
||||||
|
|
||||||
pg_hba:
|
pg_hba:
|
||||||
|
- local all all trust
|
||||||
|
- host all all 127.0.0.1/32 trust
|
||||||
|
- host replication replicator 127.0.0.1/32 trust
|
||||||
|
- host replication replicator 10.0.0.0/8 scram-sha-256
|
||||||
- host replication replicator 10.20.20.0/24 scram-sha-256
|
- host replication replicator 10.20.20.0/24 scram-sha-256
|
||||||
|
- host all all 10.0.0.0/8 scram-sha-256
|
||||||
|
- host all all 10.8.0.0/24 scram-sha-256
|
||||||
- host all all 10.20.10.0/24 scram-sha-256
|
- host all all 10.20.10.0/24 scram-sha-256
|
||||||
- host all all 10.20.20.0/24 scram-sha-256
|
- host all all 10.20.20.0/24 scram-sha-256
|
||||||
|
|
||||||
users:
|
users:
|
||||||
postgres:
|
postgres:
|
||||||
password: "${DATABASE_POSTGRES_ROOT_PASSWD}"
|
password: "${POSTGRES_PASSWORD}"
|
||||||
options:
|
options:
|
||||||
- superuser
|
- superuser
|
||||||
|
|
||||||
@ -52,12 +61,22 @@ postgresql:
|
|||||||
authentication:
|
authentication:
|
||||||
replication:
|
replication:
|
||||||
username: replicator
|
username: replicator
|
||||||
password: "${DATABASE_POSTGRES_REPLICATOR_PASSWORD}"
|
password: "${REPLICATOR_PASSWORD}"
|
||||||
superuser:
|
superuser:
|
||||||
username: postgres
|
username: postgres
|
||||||
password: "${DATABASE_POSTGRES_ROOT_PASSWD}"
|
password: "${POSTGRES_PASSWORD}"
|
||||||
parameters:
|
parameters:
|
||||||
unix_socket_directories: "/var/run/postgresql"
|
unix_socket_directories: "/var/run/postgresql"
|
||||||
|
pg_hba:
|
||||||
|
- local all all trust
|
||||||
|
- host all all 127.0.0.1/32 trust
|
||||||
|
- host replication replicator 127.0.0.1/32 trust
|
||||||
|
- host replication replicator 10.0.0.0/8 scram-sha-256
|
||||||
|
- host replication replicator 10.20.20.0/24 scram-sha-256
|
||||||
|
- host all all 10.0.0.0/8 scram-sha-256
|
||||||
|
- host all all 10.8.0.0/24 scram-sha-256
|
||||||
|
- host all all 10.20.10.0/24 scram-sha-256
|
||||||
|
- host all all 10.20.20.0/24 scram-sha-256
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
nofailover: false
|
nofailover: false
|
||||||
|
|||||||
@ -22,7 +22,8 @@
|
|||||||
- name: Add fstab entry for StorageBox
|
- name: Add fstab entry for StorageBox
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
path: /etc/fstab
|
path: /etc/fstab
|
||||||
line: "{{ storagebox_url }} {{ storagebox_mount_point }} davfs _netdev,auto,user,rw,uid=root,gid=root 0 0"
|
line: "{{ storagebox_url }} {{ storagebox_mount_point }} davfs _netdev,auto,user,rw,uid={{ storagebox_uid | default('root') }},gid={{ storagebox_gid | default('root') }} 0 0"
|
||||||
|
regexp: "^{{ storagebox_url | regex_escape() }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Mount StorageBox
|
- name: Mount StorageBox
|
||||||
@ -30,7 +31,7 @@
|
|||||||
path: "{{ storagebox_mount_point }}"
|
path: "{{ storagebox_mount_point }}"
|
||||||
src: "{{ storagebox_url }}"
|
src: "{{ storagebox_url }}"
|
||||||
fstype: davfs
|
fstype: davfs
|
||||||
opts: "_netdev,auto,user,rw,uid=root,gid=root"
|
opts: "_netdev,auto,user,rw,uid={{ storagebox_uid | default('root') }},gid={{ storagebox_gid | default('root') }}"
|
||||||
state: mounted
|
state: mounted
|
||||||
|
|
||||||
- name: Write mount marker
|
- name: Write mount marker
|
||||||
|
|||||||
@ -1,34 +1,14 @@
|
|||||||
# Prod Ortamı Kurulum Geçmişi
|
# Prod Ortamı Kurulum Geçmişi
|
||||||
|
|
||||||
İlk prod kurulumunda yaşanan sorunlar, uygulanan düzeltmeler ve mevcut durum.
|
Prod kurulum adımları ve mevcut yapı.
|
||||||
|
|
||||||
## Terraform
|
## Terraform
|
||||||
|
|
||||||
### Ayrı Hetzner Projesi Zorunluluğu
|
### Hetzner Cloud Yapılandırması
|
||||||
|
|
||||||
Test ve prod ayrı Hetzner Cloud projelerinde çalışır. Her proje için ayrı API token alınmalıdır.
|
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.
|
||||||
|
|
||||||
Aynı token kullanılırsa `terraform apply` sırasında SSH key çakışması hatası alınır:
|
Prod sunucuları `lifecycle { prevent_destroy = true }` ile korunur.
|
||||||
|
|
||||||
```
|
|
||||||
SSH key not unique (uniqueness_error, <fingerprint>)
|
|
||||||
```
|
|
||||||
|
|
||||||
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 <ID>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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
|
### Inventory Üretimi
|
||||||
|
|
||||||
@ -40,43 +20,23 @@ terraform output -raw ansible_inventory_yaml > ../../../ansible/prod/inventory/g
|
|||||||
|
|
||||||
## Ansible
|
## Ansible
|
||||||
|
|
||||||
### admin_allowed_cidrs
|
### Yapılandırma Notları
|
||||||
|
|
||||||
`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.
|
`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:
|
||||||
|
|
||||||
Doğru değer: tüm admin IP'lerini boşlukla ayrılmış string olarak içermelidir.
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
admin_allowed_cidrs: "78.187.87.109/32 95.70.151.248/32"
|
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"
|
admin_ssh_public_key_path: "~/.ssh/id_rsa.pub"
|
||||||
```
|
```
|
||||||
|
|
||||||
### PermitRootLogin
|
Hardening rolü `PermitRootLogin prohibit-password` uygular — key tabanlı root girişi açık, parola ile root girişi kapalıdır.
|
||||||
|
|
||||||
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.
|
`vault_iklim_password` per-host `host_vars/<hostname>/vault.yml` dosyalarında tanımlıdır, her sunucu farklı şifreye sahiptir:
|
||||||
|
|
||||||
**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/<hostname>/vault.yml` yapısına geçildi:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
prod/
|
prod/
|
||||||
group_vars/all/vault.yml ← vault_iklim_password KALDIRILDI
|
|
||||||
host_vars/
|
host_vars/
|
||||||
iklim-app-01/vault.yml ← vault_iklim_password: "<şifre>"
|
iklim-app-01/vault.yml
|
||||||
iklim-app-02/vault.yml
|
iklim-app-02/vault.yml
|
||||||
iklim-app-03/vault.yml
|
iklim-app-03/vault.yml
|
||||||
iklim-db-01/vault.yml
|
iklim-db-01/vault.yml
|
||||||
@ -84,44 +44,122 @@ prod/
|
|||||||
iklim-db-03/vault.yml
|
iklim-db-03/vault.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
Her dosya ayrı ayrı şifrelenir: `ansible-vault encrypt host_vars/<hostname>/vault.yml`
|
|
||||||
|
|
||||||
### StorageBox Mount
|
### 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.
|
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ı
|
### Bootstrap Çalıştırma Sırası
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd Environment_Infrastructure/ansible/prod
|
cd Environment_Infrastructure/ansible/prod
|
||||||
|
|
||||||
# 1. Tüm node'lar
|
# 1. Tüm node'lar — base, hardening, docker, dizinler, storagebox
|
||||||
ansible-playbook prod-bootstrap.yml \
|
ansible-playbook prod-bootstrap.yml \
|
||||||
--tags base,hardening,docker,node_dirs,storagebox,storagebox_ssh_key \
|
--tags base,hardening,docker,node_dirs,storagebox,storagebox_ssh_key \
|
||||||
--ask-vault-pass
|
--vault-password-file=../.vault_pass
|
||||||
|
|
||||||
# 2. Swarm kurulumu
|
# 2. Swarm kurulumu
|
||||||
ansible-playbook prod-bootstrap.yml \
|
ansible-playbook prod-bootstrap.yml \
|
||||||
--tags swarm \
|
--tags swarm \
|
||||||
--ask-vault-pass
|
--vault-password-file=../.vault_pass
|
||||||
|
|
||||||
# 3. DB node label'ları
|
# 3. DB node label'ları
|
||||||
ansible-playbook prod-bootstrap.yml \
|
ansible-playbook prod-bootstrap.yml \
|
||||||
--tags db_labels \
|
--tags db_labels \
|
||||||
--ask-vault-pass
|
--vault-password-file=../.vault_pass
|
||||||
|
|
||||||
# 4. DB node konfigürasyonu
|
# 4. DB node konfigürasyonu (StorageBox dizinleri, patroni.yml, mongod.conf, keyfile)
|
||||||
ansible-playbook prod-bootstrap.yml \
|
ansible-playbook prod-bootstrap.yml \
|
||||||
--tags db_stack \
|
--tags db_stack \
|
||||||
--ask-vault-pass
|
--limit db \
|
||||||
|
--vault-password-file=../.vault_pass
|
||||||
|
|
||||||
# 5. Act runner kurulumu
|
# 5. Act runner kurulumu
|
||||||
ansible-playbook prod-bootstrap.yml \
|
ansible-playbook prod-bootstrap.yml \
|
||||||
--tags act_runner \
|
--tags act_runner \
|
||||||
--ask-vault-pass
|
--vault-password-file=../.vault_pass
|
||||||
```
|
```
|
||||||
|
|
||||||
## Mevcut Durum (2026-05-19)
|
## 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 |
|
| Adım | Durum |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
@ -129,10 +167,11 @@ ansible-playbook prod-bootstrap.yml \
|
|||||||
| Ansible base + hardening + docker + node_dirs | ✅ |
|
| Ansible base + hardening + docker + node_dirs | ✅ |
|
||||||
| Ansible storagebox + storagebox_ssh_key | ✅ |
|
| Ansible storagebox + storagebox_ssh_key | ✅ |
|
||||||
| Ansible swarm (3 manager app + 3 worker db) | ✅ |
|
| Ansible swarm (3 manager app + 3 worker db) | ✅ |
|
||||||
| Ansible db_labels (Patroni koordinasyonu için) | ✅ |
|
| Ansible db_labels | ✅ |
|
||||||
| Ansible db_stack (StorageBox DB dizinleri) | ✅ |
|
| Ansible db_stack (StorageBox DB dizinleri + config) | ✅ |
|
||||||
| Ansible act_runner (3 prod runner Gitea'da Idle) | ✅ |
|
| Ansible act_runner (3 prod runner Gitea'da Idle) | ✅ |
|
||||||
| DB stack deploy (docker-stack-db.prod.yml) | ⏳ bekliyor |
|
| DB stack deploy (etcd + MongoDB + Patroni) | ✅ |
|
||||||
| MongoDB replica set init | ⏳ bekliyor |
|
| 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 |
|
| Ana infra stack deploy (docker-stack-infra.prod.yml) | ⏳ bekliyor |
|
||||||
| Deploy pipeline ilk çalışma | ⏳ bekliyor |
|
| Deploy pipeline ilk çalışma | ⏳ bekliyor |
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user