# 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/ ``` ## 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` 6. Tüm node'lar `AVAILABILITY=Active` kalır. ## 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 ed25519 SSH anahtar çifti üretilir ve StorageBox ana hesabına yüklenir. ## 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`) inspect ile doğrulanır. - Her node'da `/mnt/storagebox` mount edilmiştir. - Public firewall sadece `22`, `80`, `443` ingress'e izin verir.