Ansible ile Sunucu Otomasyonu: Infrastructure as Code
Ansible kurulumu, inventory dosyası, playbook yazımı, rol yapısı, değişkenler, şifreli vault, ad-hoc komutlar ve sunucu yapılandırma otomasyonu. Adım adım rehber.
İçindekiler
Ansible ile Sunucu Otomasyonu: Infrastructure as Code
Ansible, sunucu yapılandırmasını, uygulama dağıtımını ve görev otomasyonunu kod olarak yönetmenizi sağlayan açık kaynaklı bir araçtır. Agentsız mimarisi sayesinde hedef sunuculara yalnızca SSH ile bağlanır.
Ansible Nedir?
Ansible'ın temel özellikleri:
- Agentsız: Hedef sunuculara ek yazılım kurulumu gerekmez
- Idempotent: Aynı playbook birden fazla çalıştırılsa da sonuç değişmez
- YAML tabanlı: Okunması ve yazılması kolay
- Geniş modül kütüphanesi: 3000+ hazır modül
Ansible, kontrol düğümünden (control node) hedef sunuculara SSH üzerinden bağlanır. Windows sunucular için WinRM kullanılır.
Ansible Kurulumu
Ubuntu/Debian
# PPA deposunu ekle
sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible -y
# Sürümü kontrol et
ansible --version
RHEL/CentOS/AlmaLinux
# EPEL deposunu ekle
sudo dnf install epel-release -y
sudo dnf install ansible -y
# Alternatif: pip ile kur
pip3 install ansible
pip ile Kurulum (Önerilen)
# Python sanal ortamı oluştur
python3 -m venv ansible-env
source ansible-env/bin/activate
# Ansible ve ek araçları kur
pip install ansible ansible-lint
# Sürümü kontrol et
ansible --version
Inventory Dosyası
Inventory, Ansible'ın yöneteceği sunucuları tanımlar:
INI Formatı
# /etc/ansible/hosts veya özel inventory dosyası
# Tekil sunucu
web1.example.com
# Grup tanımlama
[webservers]
web1.example.com
web2.example.com ansible_port=2222
192.168.1.10 ansible_user=ubuntu
[databases]
db1.example.com
db2.example.com
# Grup değişkenleri
[webservers:vars]
ansible_user=deploy
ansible_python_interpreter=/usr/bin/python3
# Üst grup
[production:children]
webservers
databases
YAML Formatı
# inventory.yml
all:
children:
webservers:
hosts:
web1.example.com:
ansible_port: 22
web2.example.com:
ansible_port: 2222
vars:
ansible_user: deploy
http_port: 80
databases:
hosts:
db1.example.com:
db2.example.com:
vars:
ansible_user: dbadmin
db_port: 5432
staging:
hosts:
staging.example.com:
ansible_host: 192.168.1.50
Ad-hoc Komutlar
Hızlı görevler için playbook yazmadan komut çalıştırın:
# Ping testi
ansible all -m ping
ansible webservers -m ping -i inventory.yml
# Komut çalıştır
ansible all -m command -a "uptime"
ansible webservers -m shell -a "df -h"
# Dosya kopyala
ansible webservers -m copy -a "src=/local/file dest=/remote/path"
# Paket kur
ansible webservers -m apt -a "name=nginx state=present" --become
# Servis yönet
ansible webservers -m service -a "name=nginx state=started enabled=yes" --become
# Dosya oluştur/sil
ansible all -m file -a "path=/tmp/test state=touch"
ansible all -m file -a "path=/tmp/test state=absent"
# Fact topla
ansible web1.example.com -m setup
ansible all -m setup -a "filter=ansible_os_family"
Playbook Yazımı
Temel Playbook Yapısı
# site.yml
---
- name: Web sunucularını yapılandır
hosts: webservers
become: yes # sudo kullan
vars:
http_port: 80
max_clients: 200
tasks:
- name: Nginx kur
apt:
name: nginx
state: present
update_cache: yes
- name: Nginx yapılandırmasını kopyala
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
notify: Nginx yeniden başlat
- name: Nginx servisini başlat
service:
name: nginx
state: started
enabled: yes
handlers:
- name: Nginx yeniden başlat
service:
name: nginx
state: restarted
Tasks, Handlers ve Roles
# Koşullu görevler
- name: Ubuntu'da paket kur
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- curl
- git
when: ansible_os_family == "Debian"
- name: RHEL'de paket kur
dnf:
name: "{{ item }}"
state: present
loop:
- nginx
- curl
- git
when: ansible_os_family == "RedHat"
# Döngü ile kullanıcı oluştur
- name: Kullanıcıları oluştur
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
state: present
loop:
- { name: 'ali', groups: 'sudo' }
- { name: 'veli', groups: 'www-data' }
# Kayıt ve koşul
- name: Nginx sürümünü kontrol et
command: nginx -v
register: nginx_version
ignore_errors: yes
- name: Nginx kurulu değilse kur
apt:
name: nginx
state: present
when: nginx_version.rc != 0
Variables ve Facts
# group_vars/webservers.yml
http_port: 80
https_port: 443
app_user: www-data
app_dir: /var/www/html
# host_vars/web1.example.com.yml
ansible_host: 192.168.1.10
server_name: web1.example.com
# Playbook içinde değişken kullanımı
- name: Uygulama dizini oluştur
file:
path: "{{ app_dir }}"
state: directory
owner: "{{ app_user }}"
mode: '0755'
# Facts kullanımı
- name: Sistem bilgilerini göster
debug:
msg: |
OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
CPU: {{ ansible_processor_vcpus }} çekirdek
RAM: {{ ansible_memtotal_mb }} MB
IP: {{ ansible_default_ipv4.address }}
Ansible Vault
Hassas verileri şifrelemek için:
# Şifreli dosya oluştur
ansible-vault create secrets.yml
# Mevcut dosyayı şifrele
ansible-vault encrypt vars/passwords.yml
# Şifreli dosyayı düzenle
ansible-vault edit secrets.yml
# Şifreyi görüntüle
ansible-vault view secrets.yml
# Şifrelemeyi kaldır
ansible-vault decrypt vars/passwords.yml
# Şifreyi değiştir
ansible-vault rekey secrets.yml
# Vault ile playbook çalıştır
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file ~/.vault_pass
# secrets.yml (şifreli içerik)
db_password: "gizli_veritabani_sifresi"
api_key: "gizli_api_anahtari"
ssl_cert_key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
Rol Yapısı
# Rol oluştur
ansible-galaxy init roles/nginx
# Rol dizin yapısı
roles/nginx/
├── defaults/
│ └── main.yml # Varsayılan değişkenler
├── files/
│ └── nginx.conf # Statik dosyalar
├── handlers/
│ └── main.yml # Handler'lar
├── meta/
│ └── main.yml # Rol meta bilgileri
├── tasks/
│ └── main.yml # Ana görevler
├── templates/
│ └── vhost.conf.j2 # Jinja2 şablonları
└── vars/
└── main.yml # Değişkenler
# roles/nginx/tasks/main.yml
---
- name: Nginx kur
package:
name: nginx
state: present
- name: Nginx yapılandır
template:
src: vhost.conf.j2
dest: /etc/nginx/sites-available/{{ site_name }}
notify: Nginx yeniden yükle
- name: Siteyi etkinleştir
file:
src: /etc/nginx/sites-available/{{ site_name }}
dest: /etc/nginx/sites-enabled/{{ site_name }}
state: link
notify: Nginx yeniden yükle
Örnek Playbook'lar
Nginx Kurulum Playbook'u
---
- name: Nginx web sunucusu kurulumu
hosts: webservers
become: yes
vars:
domain: example.com
web_root: /var/www/{{ domain }}
tasks:
- name: Nginx kur
apt:
name: nginx
state: present
update_cache: yes
- name: Web dizini oluştur
file:
path: "{{ web_root }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Örnek index.html oluştur
copy:
content: "<h1>Merhaba {{ inventory_hostname }}</h1>"
dest: "{{ web_root }}/index.html"
owner: www-data
- name: Virtual host yapılandır
template:
src: vhost.conf.j2
dest: /etc/nginx/sites-available/{{ domain }}
notify: Nginx yeniden yükle
- name: Virtual host etkinleştir
file:
src: /etc/nginx/sites-available/{{ domain }}
dest: /etc/nginx/sites-enabled/{{ domain }}
state: link
notify: Nginx yeniden yükle
- name: Default site devre dışı bırak
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: Nginx yeniden yükle
- name: UFW Nginx izni
ufw:
rule: allow
name: 'Nginx Full'
handlers:
- name: Nginx yeniden yükle
service:
name: nginx
state: reloaded
Kullanıcı Yönetimi Playbook'u
---
- name: Kullanıcı yönetimi
hosts: all
become: yes
vars_files:
- vars/users.yml
tasks:
- name: Sudo grubunu oluştur
group:
name: sudo
state: present
- name: Kullanıcıları oluştur
user:
name: "{{ item.username }}"
comment: "{{ item.full_name }}"
groups: "{{ item.groups | join(',') }}"
shell: /bin/bash
create_home: yes
state: present
loop: "{{ users }}"
- name: SSH public key ekle
authorized_key:
user: "{{ item.username }}"
key: "{{ item.ssh_key }}"
state: present
loop: "{{ users }}"
when: item.ssh_key is defined
- name: Sudo yetkisi ver
copy:
content: "{{ item.username }} ALL=(ALL) NOPASSWD:ALL"
dest: /etc/sudoers.d/{{ item.username }}
mode: '0440'
loop: "{{ users }}"
when: item.sudo | default(false)
Playbook Çalıştırma
# Temel çalıştırma
ansible-playbook site.yml
# Belirli inventory ile
ansible-playbook -i inventory.yml site.yml
# Belirli host veya grup
ansible-playbook site.yml --limit webservers
ansible-playbook site.yml --limit web1.example.com
# Dry-run (değişiklik yapmadan kontrol)
ansible-playbook site.yml --check
# Verbose mod
ansible-playbook site.yml -v
ansible-playbook site.yml -vvv
# Belirli tag'leri çalıştır
ansible-playbook site.yml --tags "nginx,ssl"
ansible-playbook site.yml --skip-tags "debug"
# Ekstra değişken
ansible-playbook site.yml -e "env=production version=1.5"
Sonuç
Ansible, sunucu otomasyonunu kod olarak yönetmenin en erişilebilir yollarından biridir. Agentsız mimarisi, geniş modül kütüphanesi ve YAML tabanlı yapısı ile hem küçük hem de büyük ölçekli altyapıları kolayca yönetebilirsiniz. Vault ile hassas verileri güvende tutarken, roller ile yeniden kullanılabilir yapılandırmalar oluşturabilirsiniz.
İlgili Makaleler
Docker Compose Rehberi: Çok Konteynerli Uygulama Yönetimi
Docker Compose ile çok konteynerli uygulama tanımlama, servis bağımlılıkları, environment variables, health check, scaling ve production deployment. Kapsamlı rehber.
GitHub Actions ile Otomatik Deployment: CI/CD Pipeline Kurulumu
GitHub Actions ile CI/CD pipeline oluşturma, Docker build ve push, SSH ile sunucuya deployment, test otomasyonu, secrets yönetimi ve workflow optimizasyonu.
Caddy Web Server Kurulumu: Otomatik HTTPS ve Reverse Proxy
Caddy web server kurulumu, Caddyfile yapılandırması, otomatik Let's Encrypt SSL, reverse proxy, static site hosting, PHP-FPM entegrasyonu ve performans ayarları.