Environment_Infrastructure/setup/02-test-ansible-bootstrap.md
Murat ÖZDEMİR 720c79d460 Add Hetzner Cloud production infrastructure with multi-node support
- This commit introduces the Terraform configuration to provision a production environment on Hetzner Cloud, building on the existing test setup.
- Key improvements and new features include:
* **Multi-node clusters:** Scaling to 3-node Swarm application and database clusters for improved resilience.
* **High availability:** Utilizing a Hetzner Floating IP for the application entry point and `spread` placement groups for fault tolerance across physical hosts.
* **Enhanced network security:** Internal management services (RabbitMQ, APISIX, Prometheus, Grafana) are restricted to the application subnet, expected to be accessed via an internal reverse proxy (SWAG).
* **Internal database replication:** New firewall rules enable PostgreSQL replication and MongoDB replica set traffic within the database subnet.
* **Refined test environment:** Updates to align `test` configuration with the new `prod` structure, including a dedicated floating IP and adjusted firewall rules.
* **Configuration standardization:** Environment-specific details moved to `locals.tf` for clarity, with upgraded server types and migration to Rocky Linux as the base image.
- Updates were also made to the latest version of Terraform to ensure consistency in the documentation
2026-05-10 15:43:22 +03:00

6.8 KiB
Raw Blame History

02 - Test Ansible Bootstrap

Bu asamanin amaci Terraform ile olusturulan test makinelerini Linux, hardening, Docker ve Swarm acisindan hazir hale getirmektir. DB yazilimi kurulumu bu asamanin disindadir.

Hedef Makineler

Host Rol
iklim-app-01 Swarm manager + app worker
iklim-db-01 Manuel DB kurulumu icin OS-hardening uygulanmis DB node

Onerilen Dosya Yapisi

ansible/
  ansible.cfg
  inventory/
    generated/
      test.yml
  group_vars/
    all.yml
    test.yml
  playbooks/
    test-bootstrap.yml
  roles/
    base/
    hardening/
    docker/
    swarm/
    node_dirs/
    storagebox/

Base Role

Tum test node'larina uygulanir:

  • dnf update
  • temel paketler:
    • curl
    • wget
    • git
    • jq
    • unzip
    • ca-certificates
    • fail2ban
    • chrony
    • python3
    • python3-pip
  • timezone: Europe/Istanbul
  • hostname ayari
  • sistem reboot gerekiyorsa kontrollu reboot

Security Hardening Role

Tum test node'larina uygulanir:

  • SSH password login kapatilir.
  • Root SSH login kapatilir.
  • Sadece SSH key ile login kalir.
  • PermitEmptyPasswords no
  • MaxAuthTries 3
  • fail2ban SSH jail aktif edilir.
  • dnf-automatic ile otomatik guvenlik guncellestirmeleri aktif edilir.
  • firewalld default:
    • incoming: deny (drop zone)
    • outgoing: allow
  • Public SSH sadece admin CIDR'dan acilir.

Not: Docker iptables kurallari firewalld ile etkilesebilir. Hetzner Cloud firewall asil dis perimeter kabul edilir; firewalld host icinde ikinci katman olarak kullanilir.

Docker Role

Sadece iklim-app-01 uzerinde zorunludur. iklim-db-01 uzerinde DB manual kurulum stratejisine gore opsiyonel tutulabilir.

Docker kurulumu resmi Docker dnf repository uzerinden yapilir:

  • Docker GPG key + dnf repository (https://download.docker.com/linux/rhel/docker-ce.repo)
  • paketler:
    • docker-ce
    • docker-ce-cli
    • containerd.io
    • docker-buildx-plugin
    • docker-compose-plugin
  • Docker servisi enabled + started

Docker convenience script kullanilmayacak. Production benzeri test ortami icin paket repository yolu tercih edilir.

Swarm Role

iklim-app-01 uzerinde:

  • docker swarm init
  • advertise addr: 10.10.10.11
  • data path addr: 10.10.10.11
  • overlay network:
    • iklimco-net
    • driver: overlay
    • attachable: true
  • Node type=service label'i ile isaretlenir:
    docker node update --label-add type=service iklim-app-01
    
  • Node AVAILABILITY=Active kalir (drain edilmez); tek node hem manager hem worker'dir.

Test tek node Swarm oldugu icin join token kullanimi yoktur.

Node Directory Role

iklim-app-01 uzerinde deploy on kosullari:

/opt/iklimco
/opt/iklimco/ssl
/opt/iklimco/init
/opt/iklimco/init/postgresql
/opt/iklimco/init/mongodb

DB node uzerinde manuel DB kurulumu icin minimum:

/opt/iklimco
/opt/iklimco/db
/opt/iklimco/backup

StorageBox DAVFS Mount Role

Her iki node'a uygulanir (iklim-app-01 ve iklim-db-01).

Amac

Hetzner StorageBox'u WebDAV (DAVFS) protokolü üzerinden /mnt/storagebox olarak mount eder. Docker volume'lari bu dizine baglanarak veri kaliciligini ve yedeklemeyi saglar.

Test Ortami Sub-Account

Parametre Degisken Deger
Ana hesap storagebox_account u469968
Sub-account storagebox_user u469968-sub1
WebDAV URL storagebox_url https://u469968-sub1.your-storagebox.de/
Mount point storagebox_mount_point /mnt/storagebox

Role Degiskenleri

group_vars/all.yml — tum ortamlar icin ortak:

storagebox_account: "u469968"

group_vars/test.yml — test ortamina ozgu; user ve url account'tan turetilir:

storagebox_user: "{{ storagebox_account }}-sub1"
storagebox_url: "https://{{ storagebox_user }}.your-storagebox.de/"
storagebox_password: "{{ vault_storagebox_password }}"   # Ansible Vault ile saklanir
storagebox_mount_point: "/mnt/storagebox"

Prod ortaminda yalnizca suffix degisir (sub1sub2), geri kalan her sey turetilir.

vault_storagebox_password degeri Ansible Vault ile sifreli group_vars/test-vault.yml icinde tutulur:

# Sifreleme
ansible-vault encrypt group_vars/test-vault.yml

# Duzenleme
ansible-vault edit group_vars/test-vault.yml

test-vault.yml icerigi:

vault_storagebox_password: "SUB_ACCOUNT_PAROLASI"

Adimlar

  1. davfs2 kurulumu

    - name: Install davfs2
      ansible.builtin.dnf:
        name: davfs2
        state: present
    
  2. Kimlik bilgileri dosyasi (/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
    
  3. Mount point olustur

    - name: Create mount point
      ansible.builtin.file:
        path: "{{ storagebox_mount_point }}"
        state: directory
        mode: "0755"
    
  4. 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
    
  5. Mount et

    - name: Mount StorageBox
      ansible.builtin.command: mount {{ storagebox_mount_point }}
      args:
        creates: "{{ storagebox_mount_point }}/.mounted_marker"
    

    Mount basarisi icin dizine bir marker dosyasi yazilabilir:

    - name: Write mount marker
      ansible.builtin.copy:
        content: "mounted by ansible"
        dest: "{{ storagebox_mount_point }}/.mounted_marker"
    

Notlar

  • davfs2 paketi EPEL repository'sinde bulunur; base role'de dnf install epel-release yapilmalidir.
  • StorageBox sifreleri asla plaintext olarak repository'e eklenmez; Ansible Vault zorunludur.
  • Mount noktasi reboot'ta _netdev flag'i sayesinde network hazir olduktan sonra otomatik mount edilir.
  • Docker volume'lari bu dizin altindaki bir alt klasore yonlendirilir, ornegin /mnt/storagebox/volumes/.

Kabul Kriterleri

  • ansible -i inventory/generated/test.yml all -m ping basarili olur.
  • iklim-app-01 uzerinde docker info calisir.
  • iklim-app-01 uzerinde Swarm active olur; node AVAILABILITY=Active (drain degil).
  • docker network ls icinde iklimco-net gorulur.
  • docker node inspect iklim-app-01 --format '{{.Spec.Labels}}' ciktisi map[type:service] icerir.
  • iklim-db-01 uzerinde public DB portu acik degildir.
  • Public portlar Hetzner firewall + firewalld seviyesinde 22, 80, 443 ile sinirlidir.
  • Her iki node'da mount | grep storagebox StorageBox mount'unu gosterir.
  • ls /mnt/storagebox/.mounted_marker basarili olur.
  • Reboot sonrasi mount otomatik olarak geri gelir.