Docker, tek bir uygulamayı paketlemenin sorununu çözer; ama gerçek bir altyapıda onlarca sunucunun her birine Docker’ı kurmak, güvenlik ayarlarını yapmak, kullanıcıları oluşturmak ve container’ları dağıtmak gibi tekrarlayan işler de vardır. Bunları elle, sunucu sunucu SSH’layarak yapmak hem yorucu hem hataya açıktır. Ansible, bu tür sunucu ve altyapı otomasyonunu YAML ile tarif edilen, tekrar çalıştırıldığında hep aynı sonucu veren (idempotent) “playbook”lar üzerinden çözer.

Ansible’ı farklı kılan ne?

Chef, Puppet gibi diğer otomasyon araçlarının aksine Ansible’ın iki temel özelliği onu özellikle yeni başlayanlar için erişilebilir kılar:

  • Agentless (ajansız): Yönettiğiniz sunuculara herhangi bir yazılım kurmanıza gerek yok. Ansible, standart SSH üzerinden bağlanır ve komutları çalıştırır; sadece kontrol makinenizde (Ansible’ın çalıştığı bilgisayar) Python ve Ansible kurulu olması yeterlidir.
  • Deklaratif YAML: “Şu adımları çalıştır” yerine “sunucunun son hali şöyle olsun” dersiniz — Docker’ın kurulu olması, belirli bir kullanıcının var olması gibi. Ansible, o son duruma zaten ulaşılmışsa hiçbir şey değiştirmez (idempotency) — playbook’u güvenle defalarca çalıştırabilirsiniz.

Kurulum ve inventory (envanter) dosyası

# Kontrol makinenize (yönetilen sunuculara değil!) kurulum
pip install ansible --break-system-packages

ansible --version

Ansible’a hangi sunucuları yöneteceğinizi bir inventory dosyasıyla söylersiniz:

# inventory.ini
[web]
web1.ornek.com
web2.ornek.com

[db]
db1.ornek.com ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/prod.pem

[web:vars]
ortam=production
# Tüm sunuculara SSH ile erişebildiğinizi doğrulayın
ansible all -i inventory.ini -m ping

-m ping, Ansible’ın “modül” (module) çalıştırma mantığının en basit örneğidir: her komut aslında bir modülü (ping, apt, copy, docker_container gibi) belirttiğiniz sunucularda çalıştırır.

İlk playbook: sunuculara Docker kurmak

# docker-kur.yml
---
- name: Docker Engine'i kur ve yapılandır
  hosts: web
  become: true    # sudo ile çalıştır

  tasks:
    - name: Gerekli paketleri kur
      apt:
        name:
          - ca-certificates
          - curl
          - gnupg
        state: present
        update_cache: true

    - name: Docker'ın resmi kurulum betiğini indir
      get_url:
        url: https://get.docker.com
        dest: /tmp/get-docker.sh
        mode: '0755'

    - name: Docker'ı kur
      command: sh /tmp/get-docker.sh
      args:
        creates: /usr/bin/docker    # zaten kuruluysa tekrar çalıştırma

    - name: Kullanıcıyı docker grubuna ekle
      user:
        name: "{{ ansible_user }}"
        groups: docker
        append: true

    - name: Docker servisinin açılışta başladığından emin ol
      systemd:
        name: docker
        enabled: true
        state: started
ansible-playbook -i inventory.ini docker-kur.yml

Bu playbook’u web grubundaki iki sunucuya karşı çalıştırdığınızda, Ansible her görevi (task) sırayla uygular ve zaten o durumda olan bir sunucuda hiçbir değişiklik yapmaz — çıktıda changed yerine ok görürsünüz. Bu, playbook’u üçüncü, dördüncü kez çalıştırmaktan çekinmemenizi sağlar.

✓

creates: /usr/bin/docker satırı idempotency’nin somut bir örneği: Ansible bu dosya zaten varsa komutu atlar. Elle yazdığınız command/shell görevlerinde bu tür bir koruma eklemek, playbook’un güvenle tekrar çalıştırılabilir kalmasını sağlar.

community.docker koleksiyonuyla container dağıtmak

Ansible’ın resmi community.docker koleksiyonu, docker_container ve docker_compose_v2 gibi modüllerle container’ları da doğrudan yönetmenizi sağlar — sunucu kurulumuyla container dağıtımını tek bir playbook’ta birleştirebilirsiniz:

ansible-galaxy collection install community.docker
# container-dagit.yml
---
- name: Uygulama container'ını dağıt
  hosts: web
  become: true

  tasks:
    - name: En güncel imajı çek
      community.docker.docker_image:
        name: kullanici-adi/benim-api
        tag: latest
        source: pull
        force_source: true

    - name: Container'ı (yoksa) oluştur, (varsa) günceltilmiş imajla yeniden başlat
      community.docker.docker_container:
        name: benim-api
        image: kullanici-adi/benim-api:latest
        state: started
        restart_policy: unless-stopped
        recreate: true
        ports:
          - "8080:8080"
        env:
          DATABASE_URL: "{{ vault_database_url }}"

Buradaki vault_database_url değişkeni, gizli bilgilerin playbook’a açık metin olarak yazılmasını önlemek için Ansible Vault ile şifrelenmiş bir dosyadan gelir (ansible-vault create secrets.yml) — tıpkı Docker’da secret’ları imaja gömmemek gerektiği gibi, Ansible playbook’larında da parolalar asla düz metin tutulmamalıdır.

Roller: playbook’ları yeniden kullanılabilir hale getirmek

Playbook’lar büyüdükçe, ilgili görevleri, dosyaları ve varsayılan değişkenleri bir arada tutan role (rol) yapısına geçilir — tıpkı bir Docker imajını farklı projelerde yeniden kullanmak gibi, bir Ansible rolünü de (örneğin “docker-kurulumu” rolü) farklı projelerde tekrar tekrar kullanabilirsiniz:

ansible-galaxy init roles/docker-kurulumu
roles/
  docker-kurulumu/
    tasks/main.yml       # yukarıdaki görevler buraya taşınır
    handlers/main.yml    # örn. "docker'ı yeniden başlat" gibi tetiklenen eylemler
    defaults/main.yml    # varsayılan değişkenler
    templates/           # Jinja2 şablonları (örn. daemon.json)
# site.yml — rolleri birleştiren ana playbook
---
- hosts: web
  become: true
  roles:
    - docker-kurulumu
    - uygulama-dagitimi

Ansible, Docker Compose ve Kubernetes ile nasıl bir arada durur?

Araç Hangi katmanı yönetir?
Dockerfile Tek bir imajın içeriği
Docker Compose Tek sunucuda birden fazla container’ın birlikte çalışması
Ansible Sunucuların kendisi: paket kurulumu, kullanıcılar, güvenlik ayarları, birden fazla sunucuya tutarlı dağıtım
Kubernetes Container’ların bir kümede orkestrasyonu, ölçekleme, self-healing

Bu araçlar birbirini dışlamaz, farklı sorunları çözer. Yaygın bir gerçek dünya deseni: Ansible ile sunucuları (veya Kubernetes node’larının kendisini) hazırlamak, Docker Compose veya Kubernetes ile üzerlerindeki uygulamaları çalıştırmak.

Sunucularınız artık kod olarak, tutarlı ve tekrarlanabilir şekilde yapılandırılıyor. Bir adım daha geriye gidip, bu sunucuların kendisinin (bulut sağlayıcıda bir VM, ağ, güvenlik grubu) nasıl otomatik olarak oluşturulacağını ele almak için sırada Terraform ile altyapıyı kodlama var.