Add the Ansible README and expand prod bootstrap coverage for StorageBox keys, DB labels, DB stack configuration, and act runner setup. Update MongoDB configuration for replica set support and refresh prod roadmap/setup documentation for Swarm labels, StorageBox-backed cert paths, and recovery guidance.
277 lines
8.2 KiB
Markdown
277 lines
8.2 KiB
Markdown
# 07 - Prod Ansible Bootstrap
|
||
|
||
Bu aşamanın amacı Terraform ile oluşturulan prod makinelerini Linux, security hardening, Docker ve Swarm açısından hazır hale getirmektir. DB cluster yazılımı bu playbook tarafından kurulmaz; ancak DB node'ları Swarm'a worker olarak katılır.
|
||
|
||
## Ansible Kurulumu
|
||
|
||
Ansible, kontrol makinesinde (kendi bilgisayarınızda) yüklü olmalıdır. Hedef sunuculara herhangi bir ajan kurulmaz, sadece SSH erişimi yeterlidir.
|
||
|
||
### İşletim Sistemine Göre Kurulum
|
||
|
||
- **Ubuntu / Debian:**
|
||
```bash
|
||
sudo apt update
|
||
sudo apt install -y pipx python3-venv
|
||
|
||
pipx ensurepath
|
||
export PATH="$HOME/.local/bin:$PATH"
|
||
|
||
pipx install --include-deps ansible
|
||
```
|
||
|
||
- **Fedora / Rocky Linux / RHEL:**
|
||
```bash
|
||
sudo dnf install -y pipx python3-virtualenv
|
||
|
||
pipx ensurepath
|
||
export PATH="$HOME/.local/bin:$PATH"
|
||
|
||
pipx install --include-deps ansible
|
||
```
|
||
|
||
- **macOS (Homebrew):**
|
||
```bash
|
||
brew install ansible
|
||
```
|
||
|
||
- **Python Pip ile (Her platformda):**
|
||
```bash
|
||
pipx install --include-deps ansible
|
||
```
|
||
|
||
### Ek Python Bağımlılıkları
|
||
|
||
`password_hash` filtresi için `passlib` kontrol makinesinde gereklidir:
|
||
|
||
```bash
|
||
pipx inject ansible passlib
|
||
```
|
||
|
||
> `pip` ile kurduysanız: `pip install passlib`
|
||
|
||
### Kurulumun Doğrulanması
|
||
|
||
Hangi yöntemle kurarsanız kurun, kurulumun başarılı olduğunu doğrulamak için aşağıdaki komutları kullanın:
|
||
|
||
```bash
|
||
# Ansible versiyonunu ve yapılandırma yollarını kontrol edin
|
||
ansible --version
|
||
|
||
# Ansible binary’sinin hangi konumdan çalıştığını kontrol edin
|
||
which -a ansible
|
||
```
|
||
|
||
## Ansible Komutlarını Çalıştırma
|
||
|
||
Tüm komutlar `ansible/prod/` dizininden çalıştırılmalıdır. `ansible.cfg` inventory ve roles_path'i otomatik olarak tanımlar.
|
||
|
||
### 0. Gerekli Collection'ları Kur (İlk kurulumda bir kez)
|
||
|
||
```bash
|
||
ansible-galaxy collection install -r ../requirements.yml
|
||
```
|
||
|
||
### 1. Bağlantı Testi (Ping)
|
||
|
||
```bash
|
||
ansible all -m ping
|
||
```
|
||
|
||
### 2. Bootstrap Playbook'unu Çalıştırma
|
||
|
||
```bash
|
||
ansible-playbook prod-bootstrap.yml --ask-vault-pass
|
||
```
|
||
|
||
*Not: `--ask-vault-pass` parametresi Ansible Vault parolasını sorar; StorageBox şifresi bu şekilde çözülür.*
|
||
|
||
### 3. Sadece Belirli Bir Rolü Çalıştırma (Tags)
|
||
|
||
```bash
|
||
ansible-playbook prod-bootstrap.yml --tags "hardening" --ask-vault-pass
|
||
```
|
||
|
||
## Hedef Makineler
|
||
|
||
| Host | Rol |
|
||
| --- | --- |
|
||
| `iklim-app-01` | Swarm manager + app worker |
|
||
| `iklim-app-02` | Swarm manager + app worker |
|
||
| `iklim-app-03` | Swarm manager + app worker |
|
||
| `iklim-db-01` | Manuel DB cluster node |
|
||
| `iklim-db-02` | Manuel DB cluster node |
|
||
| `iklim-db-03` | Manuel DB cluster node |
|
||
|
||
## Önerilen Dosya Yapısı
|
||
|
||
```text
|
||
ansible/
|
||
prod/
|
||
ansible.cfg
|
||
inventory/
|
||
generated/
|
||
prod.yml
|
||
group_vars/
|
||
all/
|
||
vars.yml
|
||
vault.yml
|
||
prod-bootstrap.yml
|
||
roles/
|
||
base/
|
||
hardening/
|
||
docker/
|
||
swarm/
|
||
node_dirs/
|
||
storagebox/
|
||
storagebox_ssh_key/
|
||
act_runner/
|
||
db_stack/
|
||
```
|
||
|
||
## Base Role
|
||
|
||
Tüm prod node'larına uygulanır:
|
||
|
||
- Paket cache update
|
||
- `epel-release` — ayrı task olarak önce kurulur; `fail2ban`, `davfs2`, `htop`, `btop` bu repoya bağımlı
|
||
- temel paketler (`epel-release` aktif olduktan sonra):
|
||
- `curl`
|
||
- `wget`
|
||
- `git`
|
||
- `jq`
|
||
- `tar`
|
||
- `unzip`
|
||
- `bash-completion`
|
||
- `gettext` — envsubst için; CI/CD deploy pipeline'larında gerekli
|
||
- `tree`
|
||
- `ca-certificates`
|
||
- `fail2ban`
|
||
- `chrony`
|
||
- `python3`
|
||
- `python3-pip`
|
||
- `python3-passlib` — `password_hash` filtresi için (EPEL)
|
||
- `htop` — interaktif proses izleme (EPEL)
|
||
- `btop` — kaynak monitörü, grafik arayüz (EPEL)
|
||
- timezone: `Europe/Istanbul`
|
||
- hostname ayarı
|
||
- klavye düzeni: `trq` (Türkçe Q)
|
||
- chrony/NTP aktif
|
||
|
||
## Security Hardening Role
|
||
|
||
Tüm prod node'larına uygulanır:
|
||
|
||
- SSH password auth kapatılır.
|
||
- Root SSH login kapatılır.
|
||
- Sadece SSH key auth kalır.
|
||
- `PermitEmptyPasswords no`
|
||
- `MaxAuthTries 3`
|
||
- `fail2ban` aktif edilir.
|
||
- `dnf-automatic` ile otomatik güvenlik güncelleştirmeleri aktif edilir.
|
||
- `iklim` sistem kullanıcısı oluşturulur; `wheel` grubuna eklenir (şifre vault'tan alınır).
|
||
- `firewalld` default: incoming deny (drop zone), outgoing allow.
|
||
- SSH kuralı önce `drop` zone'a rich rule olarak yazılır, ardından default zone `drop` yapılır.
|
||
- SSH sadece admin CIDR'dan açılır.
|
||
- DB portları public açılmaz.
|
||
|
||
Hetzner Cloud Firewall asıl perimeter kabul edilir. firewalld host üzerinde ikinci savunma katmanıdır.
|
||
|
||
## Docker Role
|
||
|
||
Tüm prod node'larında (hem app hem db) zorunludur. DB node'ları Swarm Worker olarak ağa dahil olacağı için Docker Engine her makinede kurulu olmalıdır.
|
||
|
||
Kurulacak paketler:
|
||
|
||
- `docker-ce`
|
||
- `docker-ce-cli`
|
||
- `containerd.io`
|
||
- `docker-buildx-plugin`
|
||
- `docker-compose-plugin`
|
||
|
||
Kurulum resmi Docker dnf repository üzerinden yapılacak (`https://download.docker.com/linux/rhel/docker-ce.repo`).
|
||
|
||
## Swarm Role
|
||
|
||
Prod Swarm 3 manager ile kurulacak:
|
||
|
||
1. `iklim-app-01` üzerinde `docker swarm init` (Advertise/data path addr: `10.20.10.11`)
|
||
2. `iklim-app-02` ve `iklim-app-03` manager olarak join olur.
|
||
3. `iklim-db-01/02/03` worker olarak join olur.
|
||
4. Overlay network oluşturulur: `iklimco-net`
|
||
5. Node etiketleri:
|
||
- `iklim-app-*` -> `type=service`
|
||
- `iklim-db-*` -> `role=db`, `db-index=01/02/03` (Patroni node koordinasyonu için)
|
||
6. Tüm node'lar `AVAILABILITY=Active` kalır.
|
||
|
||
`db-index` etiketleri prod-bootstrap.yml içinde ayrı bir play ile `iklim-app-01` üzerinden eklenir (swarm role tarafından değil).
|
||
|
||
## Node Directory Role
|
||
|
||
Tüm `iklim-app-*` node'larında:
|
||
```text
|
||
/opt/iklimco/ssl
|
||
/opt/iklimco/init
|
||
/opt/iklimco/stacks
|
||
```
|
||
|
||
DB node'larında:
|
||
```text
|
||
/opt/iklimco/db
|
||
/opt/iklimco/backup
|
||
```
|
||
|
||
## StorageBox DAVFS Mount Role
|
||
|
||
Her node'a uygulanır (tüm `iklim-app-*` ve `iklim-db-*`).
|
||
|
||
### Prod Sub-Account
|
||
|
||
| Parametre | Değişken | Değer |
|
||
| --- | --- | --- |
|
||
| Ana hesap | `storagebox_account` | `u469968` |
|
||
| Sub-account | `storagebox_user` | `u469968-sub5` |
|
||
| WebDAV URL | `storagebox_url` | `https://u469968-sub5.your-storagebox.de/` |
|
||
| Mount point | `storagebox_mount_point` | `/mnt/storagebox` |
|
||
|
||
## StorageBox SSH Key Role
|
||
|
||
Her node'a uygulanır. Sunucu üzerinde `/root/.ssh/id_ed25519_storagebox` ed25519 anahtar çifti üretilir. Üretilen public key'in StorageBox ana hesabına yüklenmesi (SSH authorized_keys) ayrı bir manuel adımdır:
|
||
|
||
```bash
|
||
# Her node için:
|
||
cat /root/.ssh/id_ed25519_storagebox.pub | \
|
||
ssh -p 23 STORAGEBOX_USER@STORAGEBOX_USER.your-storagebox.de \
|
||
"cat >> .ssh/authorized_keys"
|
||
```
|
||
|
||
## Act Runner Role
|
||
|
||
`iklim-app-*` node'larına uygulanır. Her app node'a Gitea Act Runner kurulur ve systemd servisi olarak başlatılır. Prod ortamında 3 app node üzerinde runner çalışır; deploy pipeline bu runner'lardan herhangi birinde tetiklenebilir.
|
||
|
||
## DB Stack Role
|
||
|
||
`iklim-db-*` node'larına uygulanır. MongoDB için `/opt/iklimco/db/mongodb/config/` dizinini ve `mongod.conf` dosyasını oluşturur. `group_vars/prod.yml` içinde tanımlı `mongodb_replset_name: "rs0"` değişkeniyle `mongod.conf` replicaSet ve keyFile bloklarını otomatik içerir.
|
||
|
||
## /opt/iklimco/stacks/.env
|
||
|
||
DB cluster stack'lerinin gerektirdiği şifre değişkenleri `/opt/iklimco/stacks/.env` dosyasında saklanır. Bu dosya StorageBox'ta `prod/secrets/iklim.co/.env.stacks` olarak tutulur. İlk deploy öncesinde `iklim-app-01` üzerinde aşağıdaki komutla çekilir:
|
||
|
||
```bash
|
||
scp -P 23 STORAGEBOX_USER@STORAGEBOX_USER.your-storagebox.de:prod/secrets/iklim.co/.env.stacks \
|
||
/opt/iklimco/stacks/.env
|
||
chmod 600 /opt/iklimco/stacks/.env
|
||
```
|
||
|
||
## Kabul Kriterleri
|
||
|
||
- `ansible all -m ping` başarılı olur.
|
||
- 3 Swarm manager node `docker node ls` içinde Leader/Reachable görünür.
|
||
- 3 DB node `docker node ls` içinde Worker olarak görünür.
|
||
- Manager quorum sağlanır (3 manager, 1 kayıp tolere edilir).
|
||
- `iklimco-net` overlay network vardır.
|
||
- Node etiketleri (`type=service`, `role=db`, `db-index=01/02/03`) inspect ile doğrulanır.
|
||
- Her node'da `/mnt/storagebox` mount edilmiştir.
|
||
- Her app node'da Gitea Act Runner servisi çalışmaktadır.
|
||
- DB node'larında `/opt/iklimco/db/mongodb/config/mongod.conf` oluşturulmuştur ve `replSetName: rs0` içermektedir.
|
||
- Public firewall sadece `22`, `80`, `443` ingress'e izin verir.
|