Ana içeriğe geç
Kategoriye Dön

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.

Okuma süresi: 20 dk DevOps & Otomasyon
ansibleotomasyoninfrastructure as codedevopsplaybookyamllinux

İç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

hljs bash
# 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

hljs bash
# 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)

hljs bash
# 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ı

hljs ini
# /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ı

hljs yaml
# 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:

hljs bash
# 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ı

hljs yaml
# 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

hljs yaml
# 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

hljs yaml
# 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
hljs yaml
# 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:

hljs bash
# Ş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
hljs yaml
# 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ı

hljs bash
# 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
hljs yaml
# 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

hljs yaml
---
- 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

hljs yaml
---
- 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

hljs bash
# 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.