Ansible, SSH üzerinden çalışan agentless bir configuration management aracıdır. 100 sunucuya aynı paketleri kurmak, config dosyalarını dağıtmak, servisleri başlatmak — hepsi tek komutla. Python gerektirir ama hedef sunucularda zaten vardır.
Kurulum
İlgili rehberler: DNS nedir, ayarları değiştirme · Domain adı ve WHOIS sorgulama · Hosting türleri rehberi · Nginx yapılandırma · Plesk panel yönetimi
# Ubuntu/Debian
sudo apt install -y ansible
# Veya pip ile
pipx install ansible
ansible --version
# Hedef sunucuların SSH anahtarı varsa yeterli
ssh-copy-id root@web-1.example.com
Inventory
# inventory.ini
[web]
web-1.example.com
web-2.example.com
web-3.example.com ansible_host=1.2.3.4
[db]
db-1.example.com
db-2.example.com
[production:children]
web
db
[web:vars]
ansible_user=deploy
ansible_ssh_private_key_file=~/.ssh/deploy_key
# inventory.yml (alternatif)
all:
children:
web:
hosts:
web-1.example.com:
web-2.example.com:
vars:
ansible_user: deploy
db:
hosts:
db-1.example.com:
Ad-Hoc Komutlar
# Ping tüm sunucular
ansible all -i inventory.ini -m ping
# Komut çalıştır
ansible web -i inventory.ini -m shell -a 'uptime'
# Paket kur
ansible web -i inventory.ini -m apt -a 'name=htop state=present' --become
# Dosya kopyala
ansible web -i inventory.ini -m copy -a 'src=./nginx.conf dest=/etc/nginx/nginx.conf'
Playbook — Temel Örnek
# site.yml
- name: Web sunucuları sertleştir
hosts: web
become: true
vars:
ssh_port: 22022
tasks:
- name: Apt güncelle
apt:
update_cache: yes
upgrade: safe
cache_valid_time: 3600
- name: Gerekli paketler
apt:
name:
- fail2ban
- ufw
- nginx
- htop
state: present
- name: SSH port değiştir
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?Port '
line: 'Port {{ ssh_port }}'
notify: restart sshd
- name: UFW kurallar
ufw:
rule: allow
port: '{{ item }}'
loop: ['{{ ssh_port }}', '80', '443']
- name: UFW enable
ufw:
state: enabled
policy: deny
handlers:
- name: restart sshd
service: { name: ssh, state: restarted }
# Çalıştır
ansible-playbook -i inventory.ini site.yml
# Dry run
ansible-playbook -i inventory.ini site.yml --check --diff
# Sadece tek host
ansible-playbook -i inventory.ini site.yml --limit web-1.example.com
# Tek task'tan devam
ansible-playbook -i inventory.ini site.yml --start-at-task='SSH port'
Roles — Modüler Yapı
# Role iskeleti
ansible-galaxy init roles/nginx
# Yapı
roles/nginx/
├── tasks/main.yml # ana task'lar
├── handlers/main.yml # servis restart vs.
├── templates/ # jinja2 template'leri
├── files/ # statik dosyalar
├── vars/main.yml # role değişkenleri
└── defaults/main.yml # override edilebilir default'lar
# roles/nginx/tasks/main.yml
- name: Nginx kur
apt: { name: nginx, state: present }
- name: Config template
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
validate: 'nginx -t -c %s'
notify: reload nginx
- name: Servis açık
service:
name: nginx
state: started
enabled: yes
# roles/nginx/handlers/main.yml
- name: reload nginx
service: { name: nginx, state: reloaded }
# Ana playbook
- hosts: web
become: true
roles:
- nginx
Jinja2 Template
# roles/nginx/templates/nginx.conf.j2
worker_processes {{ ansible_processor_vcpus }};
worker_connections {{ worker_connections | default(1024) }};
{% for server in groups['backend'] %}
upstream backend {
server {{ hostvars[server].ansible_host }}:3000;
}
{% endfor %}
server {
listen 443 ssl;
server_name {{ server_name }};
ssl_certificate /etc/letsencrypt/live/{{ server_name }}/fullchain.pem;
}
Ansible Vault
# Şifrelenmiş secret dosyası
ansible-vault create secrets.yml
# editör açılır, içine:
# db_password: supersecret
# api_key: xyz
ansible-vault edit secrets.yml
ansible-vault encrypt existing.yml
ansible-vault decrypt encrypted.yml
# Playbook'ta kullanım
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file=.vault_pass
Gerçek Dünya: Tam Deploy Playbook
- hosts: web
become: true
vars_files:
- secrets.yml
tasks:
- name: App user oluştur
user:
name: app
home: /var/www/app
shell: /bin/bash
- name: Repo klonla/güncelle
git:
repo: 'git@github.com:user/app.git'
dest: /var/www/app
version: main
accept_hostkey: yes
become_user: app
notify: restart app
- name: NPM install
npm:
path: /var/www/app
production: yes
state: present
become_user: app
- name: Env dosyası
template:
src: env.j2
dest: /var/www/app/.env
owner: app
mode: '0600'
- name: PM2 ile çalıştır
command: pm2 startOrReload ecosystem.config.js
args: { chdir: /var/www/app }
become_user: app
handlers:
- name: restart app
command: pm2 restart ecosystem.config.js
become_user: app
Modern Web Hosting ve Sunucu Altyapısı
Performanslı bir web hosting hizmeti üç temel altyapı kararına dayanır: NVMe SSD diskler (klasik SATA SSD'ye göre 4-6 kat IOPS), LiteSpeed Web Server veya Nginx + LSCache kombinasyonu (Apache'ye göre 9 kat istek kapasitesi) ve CloudLinux + Imunify360 izolasyonu. Hosting sağlayıcısının kontrol paneli (cPanel, Plesk, DirectAdmin), günlük yedek politikası, veri merkezi konumu ve destek ekibi yanıt süresi de büyük fark yaratır. Türkiye lokasyonu yerli ziyaretçilere düşük gecikme verirken; Hetzner Frankfurt veya OVH Roubaix gibi Avrupa lokasyonları global trafik için daha uygundur. Site büyüdükçe paylaşımlı hosting'ten VPS, ardından dedicated server'a geçiş; CPU/RAM/disk kaynaklarının web sitemizin ihtiyaçlarına göre ölçeklenmesini sağlar.
Çoklu sunucu yönetimi, playbook tasarımı ve migration otomasyonu için iletişime geçin