This commit introduces a reordered and renumbered set of setup documentation files to better reflect the deployment stages for both test and production environments. Key changes include: * A new `setup-vs-roadmap-map.md` file to provide a clear mapping between roadmap tasks and their corresponding setup phases. * Significantly expanded Ansible bootstrap documentation for both test and production, detailing Docker, Swarm, security hardening, and StorageBox SSH key management roles. * Formalized database Docker and Swarm cluster setup instructions for test and production, including explicit steps for Swarm worker integration of DB nodes. * Updated roadmap documentation (`roadmap/prod-env/*`) to align with the refined setup, incorporating correct private IP addresses for Swarm joins, new node labels, and floating IP usage for GoDaddy DNS records.
12 KiB
03 - Test Ansible Bootstrap
Bu aşamanın amacı Terraform ile oluşturulan test makinelerini Linux, hardening, Docker ve Swarm açısından hazır hale getirmektir. DB yazılımı kurulumu bu aşamanın dışındadı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:
sudo apt update sudo apt install -y pipx python3-venv pipx ensurepath export PATH="$HOME/.local/bin:$PATH" pipx install --include-deps ansible
Not:
sudo apt install ansiblekomutu bazı Ubuntu/Debian sürümlerinde eski Ansible paketlerini kurabilir. Bu nedenle güncel Ansible kullanımı içinpipxyöntemi tercih edilmelidir.
-
Fedora / Rocky Linux / RHEL:
sudo dnf install -y pipx python3-virtualenv pipx ensurepath export PATH="$HOME/.local/bin:$PATH" pipx install --include-deps ansible -
macOS (Homebrew):
brew install ansible -
Python Pip ile (Her platformda):
pipx install --include-deps ansible
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:
# 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 projenin ansible/ dizini altından çalıştırılmalıdır.
1. Bağlantı Testi (Ping)
Sunuculara erişimi doğrulamak için:
ansible -i inventory/generated/test.yml all -m ping
2. Bootstrap Playbook'unu Çalıştırma
Tüm rolleri (base, hardening, docker, swarm vb.) uygulamak için:
ansible-playbook -i inventory/generated/test.yml playbooks/test-bootstrap.yml --ask-vault-pass
Not: --ask-vault-pass parametresi, hassas verilerin (StorageBox şifresi vb.) çözülmesi için gereken Ansible Vault parolasını soracaktır.
3. Sadece Belirli Bir Rolü Çalıştırma (Tags)
Sadece belirli bir kısmı güncellemek isterseniz (örneğin sadece hardening):
ansible-playbook -i inventory/generated/test.yml playbooks/test-bootstrap.yml --tags "hardening" --ask-vault-pass
Hedef Makineler
| Host | Rol |
|---|---|
iklim-app-01 |
Swarm manager + app worker |
iklim-db-01 |
Manuel DB kurulumu için OS-hardening uygulanmış DB node |
Önerilen Dosya Yapısı
ansible/
test/
ansible.cfg
inventory/
generated/
test.yml
group_vars/
all.yml
test.yml
test-bootstrap.yml
roles/
base/
hardening/
docker/
swarm/
node_dirs/
storagebox/
storagebox_ssh_key/
Base Role
Tüm test node'larına uygulanır:
dnf update- temel paketler (sırasıyla kurulur):
epel-release— fail2ban ve davfs2 bu repo'dan gelir; önce kurulurcurlwgetgitjqtarunzipbash-completiongettext— envsubst için; CI/CD deploy pipeline'larında gereklitreeca-certificatesfail2banchronypython3python3-piphtop— interaktif proses izleme (EPEL)btop— kaynak monitörü, grafik arayüz (EPEL)
- timezone:
Europe/Istanbul - hostname ayarı
- sistem reboot gerekiyorsa kontrollü reboot
Security Hardening Role
Tüm test node'larına uygulanır:
- SSH password login kapatılır.
- Root SSH login kapatılır.
- Sadece SSH key ile login kalır.
PermitEmptyPasswords noMaxAuthTries 3fail2banSSH jail aktif edilir.dnf-automaticile otomatik güvenlik güncelleştirmeleri aktif edilir.firewallddefault:- incoming: deny (drop zone)
- outgoing: allow
- Public SSH sadece admin CIDR'dan açılır.
SELinux Kararı
Rocky Linux 10 SELinux enforcing modda gelir. Karar: disabled.
Gerekçe:
- Hetzner Cloud firewall (dış perimeter) + firewalld (host) iki katman ağ güvenliğini sağlar.
- Docker + davfs2 + firewalld kombinasyonu SELinux enforcing modda ek policy ve volume label yönetimi gerektirir.
- Utils VPS'te de disabled yapılmış; tutarlılık sağlanır.
# /etc/selinux/config içinde:
SELINUX=disabled
# Değişiklik reboot sonrası aktif olur
reboot
Ansible'da:
- name: Disable SELinux
ansible.posix.selinux:
state: disabled
register: selinux_change
- name: Reboot if SELinux state changed
ansible.builtin.reboot:
when: selinux_change.changed
fail2ban Konfigürasyonu
/etc/fail2ban/jail.local içeriği:
[DEFAULT]
ignoreip = 127.0.0.1/8 {{ admin_allowed_cidrs }}
bantime = 21600
findtime = 300
maxretry = 5
banaction = iptables-multiport
backend = systemd
[sshd]
enabled = true
bantime: 6 saat banfindtime: 5 dakika içindemaxretry: 5 başarısız giriş → banignoreip: admin CIDR'ları ban'dan muaf tutar
Ansible'da admin_allowed_cidrs listesi space-separated stringe dönüştürülüp template'e basılır.
Not: Docker iptables kuralları firewalld ile etkileşebilir. Hetzner Cloud firewall asıl dış perimeter kabul edilir; firewalld host içinde ikinci katman olarak kullanılır.
Docker Role
Her iki node (iklim-app-01 ve iklim-db-01) üzerinde de zorunludur. DB node'u Swarm Worker olarak ağa dahil olacağı için Docker Engine her iki makinede de kurulu olmalıdır.
Docker kurulumu resmi Docker dnf repository üzerinden yapılır:
- Docker GPG key + dnf repository (
https://download.docker.com/linux/rhel/docker-ce.repo) - paketler:
docker-cedocker-ce-clicontainerd.iodocker-buildx-plugindocker-compose-plugin
- Docker servisi enabled + started
Docker convenience script kullanılmayacak. Production benzeri test ortamı için paket repository yolu tercih edilir.
Swarm Role
iklim-app-01üzerinde Swarm Manager olarak init edilir.iklim-db-01üzerinde Swarm Worker olarak join edilir (Overlay network erişimi için).- advertise addr:
10.10.10.11(manager için) - overlay network:
iklimco-net- driver:
overlay - attachable:
true
- Node etiketleri:
iklim-app-01->type=serviceiklim-db-01->role=db
iklim-app-01üzerinde hem manager hem worker (Active) görevini sürdürür.
Node Directory Role
iklim-app-01 üzerinde deploy ön koşulları:
/opt/iklimco
/opt/iklimco/ssl
/opt/iklimco/init
/opt/iklimco/init/postgresql
/opt/iklimco/init/mongodb
DB node üzerinde manuel DB kurulumu için minimum:
/opt/iklimco
/opt/iklimco/db
/opt/iklimco/backup
StorageBox DAVFS Mount Role
Her iki node'a uygulanır (iklim-app-01 ve iklim-db-01).
Amaç
Hetzner StorageBox'u WebDAV (DAVFS) protokolü üzerinden /mnt/storagebox olarak mount eder. Docker volume'ları bu dizine bağlanarak veri kalıcılığını ve yedeklemeyi sağlar.
Test Ortamı Sub-Account
| Parametre | Değişken | Değer |
|---|---|---|
| Ana hesap | storagebox_account |
u469968 |
| Sub-account | storagebox_user |
u469968-sub4 |
| WebDAV URL | storagebox_url |
https://u469968-sub4.your-storagebox.de/ |
| Mount point | storagebox_mount_point |
/mnt/storagebox |
Role Değişkenleri
group_vars/all.yml — tüm ortamlar için ortak:
storagebox_account: "u469968"
group_vars/test.yml — test ortamına özgü; user ve url account'tan türetilir:
storagebox_user: "{{ storagebox_account }}-sub1"
storagebox_url: "https://{{ storagebox_user }}.your-storagebox.de/"
storagebox_password: "{{ vault_storagebox_password }}" # Ansible Vault ile saklanır
storagebox_mount_point: "/mnt/storagebox"
Prod ortamında yalnızca suffix değişir (sub4 → sub5), geri kalan her şey türetilir.
vault_storagebox_password değeri Ansible Vault ile şifreli group_vars/test-vault.yml içinde tutulur:
# Sifreleme
ansible-vault encrypt group_vars/test-vault.yml
# Düzenleme
ansible-vault edit group_vars/test-vault.yml
test-vault.yml içeriği:
vault_storagebox_password: "SUB_ACCOUNT_PAROLASI"
Adımlar
-
davfs2 kurulumu
- name: Install davfs2 ansible.builtin.dnf: name: davfs2 state: present -
Kimlik bilgileri dosyası (
/etc/davfs2/secrets)- name: Configure davfs2 secrets ansible.builtin.lineinfile: path: /etc/davfs2/secrets line: "{{ storagebox_url }} {{ storagebox_user }} {{ storagebox_password }}" create: yes mode: "0600" owner: root group: root -
Mount point oluştur
- name: Create mount point ansible.builtin.file: path: "{{ storagebox_mount_point }}" state: directory mode: "0755" -
fstab kaydı
- name: Add fstab entry ansible.builtin.lineinfile: path: /etc/fstab line: >- {{ storagebox_url }} {{ storagebox_mount_point }} davfs _netdev,auto,user,rw,uid=root,gid=root 0 0 state: present -
Mount et
- name: Mount StorageBox ansible.builtin.command: mount {{ storagebox_mount_point }} args: creates: "{{ storagebox_mount_point }}/.mounted_marker"Mount başarısı için dizine bir marker dosyası yazılabilir:
- name: Write mount marker ansible.builtin.copy: content: "mounted by ansible" dest: "{{ storagebox_mount_point }}/.mounted_marker"
Notlar
davfs2paketi EPEL repository'sinde bulunur; base roleepel-release'i zaten kurar.- StorageBox şifreleri asla plaintext olarak repository'e eklenmez; Ansible Vault zorunludur.
- Mount noktası reboot'ta
_netdevflag'ı sayesinde network hazır olduktan sonra otomatik mount edilir. - Docker Swarm servisleri
/mnt/storagebox/<env>/<service>/altındaki dizinleri bind mount olarak kullanır.
StorageBox SSH Key Role
Her iki node'a uygulanır (iklim-app-01 ve iklim-db-01).
Amaç
Sunucu üzerinde ed25519 SSH anahtar çifti üretilir ve StorageBox ana hesabına yüklenir.
Bu sayede CI/CD pipeline'ları STORAGEBOX_SSH_PRIV Gitea secret'ini kullanarak
şifresiz erişim sağlayabilir.
Adımlar
-
SSH Key üretimi
- name: Generate SSH key for StorageBox ansible.builtin.user: name: root generate_ssh_key: yes ssh_key_type: ed25519 ssh_key_file: .ssh/id_ed25519_storagebox ssh_key_comment: "{{ inventory_hostname }}-storagebox" -
Public key'i StorageBox'a yükle
Bu adım manuel yapılır (ilk kez şifre gerektirir):
cat /root/.ssh/id_ed25519_storagebox.pub | ssh -p23 u469968-sub4@u469968-sub4.your-storagebox.de install-ssh-keySonraki erişimler şifresiz çalışır:
sftp -P23 u469968-sub4@u469968-sub4.your-storagebox.de -
Private ve public key'leri Gitea'ya ekle
Gitea → Organization Settings → Actions → Secrets:
Secret Adı Değer STORAGEBOX_SSH_PRIV/root/.ssh/id_ed25519_storageboxiçeriğiSTORAGEBOX_SSH_PUB/root/.ssh/id_ed25519_storagebox.pubiçeriğiKey içeriğini almak için:
cat /root/.ssh/id_ed25519_storagebox cat /root/.ssh/id_ed25519_storagebox.pub
Notlar
- Her sunucu için ayrı key üretilir; tüm public key'ler StorageBox ana hesabına yüklenir.
- Private key asla repo'ya commit edilmez; yalnızca Gitea secret olarak saklanır.