İçeriğe geç

(B) DevOps

Packer ile Otomatik VM Görüntü Oluşturma ve Yönetimi

5 dk okuma

Packer, HashiCorp'un geliştirdiği ve cloud ortamları için golden image oluşturma sürecini otomatikleştiren bir araç. Geleneksel manuel VM hazırlama yöntemlerinin yerine, tek bir konfigürasyon dosyasından birden fazla platform için (AWS, Azure, VMware, VirtualBox, DigitalOcean, GCP) aynı anda veya sırayla image üretebiliyor. Bu yaklaşım, altyapının yeniden üretilebilirliğini sağlarken provisioning süresini dramatik şekilde düşürüyor.

Temel Kavramlar

Packer'ın çalışma mantığı üç temel yapı taşı üzerine kurulu. Builder, hedef platform için VM oluşturan ve image çıkaran bileşen. Her builder kendi yöntemiyle çalışır; AWS için AMI oluşturur, VirtualBox için OVA/OVF çıktısı verir. Provisioner, VM oluşturulduktan sonra içeriye yazılım yükleyen, konfigürasyon yapan katman. Bash scriptleri, PowerShell, Ansible, Chef, Puppet, Salt gibi araçlarla bu işlem gerçekleştirilir. Post-processor ise oluşturulan image üzerinde son işlemleri yapar; örneğin Vagrant box'a dönüştürme veya compress işlemi gibi.

Kurulum ve İlk Adımlar

Linux sistemlere HashiCorp deposundan paket olarak kurulabilir ya da resmi indirme sayfasından işletim sistemine uygun binary indirilip PATH'e eklenir. Kurulum sonrası packer version komutuyla doğrulama yapılır. Çalışma prensibi oldukça basit: HCL (HashiCorp Configuration Language) formatında yazılmış template dosyası packer build komutuna verilir, araç gerekli VM'i oluşturur, provisioner'ları çalıştırır ve son image'i paketler. Builder'lar Packer'ın güncel sürümlerinde plugin olarak dağıtılır; build öncesinde template dizininde packer init çalıştırmak gerekli pluginleri indirir.

Template Yapısı

Bir Packer template'i source ve build bloklarından oluşur. Source bloğu hangi platform için hangi parametrelerle VM oluşturulacağını tanımlar. Build bloğu ise hangi source'un kullanılacağını, hangi provisioner'ların çalışacağını ve post-processors zincirini belirtir.

source "virtualbox-iso" "ubuntu-server" {
  guest_os_type      = "Ubuntu_64"
  iso_url            = "https://releases.ubuntu.com/22.04/ubuntu-22.04.3-live-server-amd64.iso"
  iso_checksum       = "sha256:abc123..."
  disk_size          = 40960
  memory             = 2048
  cpus               = 2
  ssh_username       = "ubuntu"
  ssh_password       = "ubuntu"
  ssh_port           = 22
  shutdown_command   = "echo 'ubuntu' | sudo shutdown -P now"
  vm_name            = "ubuntu-server-base"
}

build {
  name = "ubuntu-base"
  sources = ["source.virtualbox-iso.ubuntu-server"]

  provisioner "shell" {
    execute_command = "chmod +x {{ .Path }} && {{ .Vars }} {{ .Path }}"
    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y curl wget git nginx",
      "sudo systemctl enable nginx"
    ]
  }
}

Yukarıdaki örnek VirtualBox için Ubuntu Server image oluşturur. Disk boyutu 40GB, bellek 2GB, 2 CPU ayrılmıştır. SSH ile bağlanıp shell provisioner çalıştırılır; apt-get ile temel yazılımlar kurulur ve nginx servisi aktive edilir.

Farklı Platformlar İçin Aynı Template

Packer'ın güçlü yanı tek bir template'den birden fazla builder ile image üretebilmesidir. AWS ve Azure için AMI oluşturmak istendiğinde source bloğu çoğaltılır, build bloğunda her ikisi de sources listesine eklenir. Build sürecinde builder'lar varsayılan olarak paralel çalışır ve her biri kendi platformuna özgü image'i üretir. Bu yaklaşım, farklı cloud sağlayıcılarında aynı base image'i kullanmayı sağlar ve configuration drift sorunlarını ortadan kaldırır.

source "amazon-ebs" "web-server" {
  ami_name      = "web-server-{{ timestamp }}"
  instance_type = "t3.micro"
  region        = "us-east-1"
  ssh_username  = "ubuntu"
  source_ami_filter {
    filters = {
      name                = "ubuntu/images/*ubuntu-jammy-22.04-amd64-server-*"
      root-device-type    = "ebs"
      virtualization-type = "hvm"
    }
    most_recent = true
    owners      = ["099720109477"]
  }
}

source "azure-arm" "web-server" {
  os_type         = "Linux"
  image_publisher = "Canonical"
  image_offer     = "0001-com-ubuntu-server-jammy"
  image_sku       = "22_04-lts-gen2"
  location        = "westeurope"
  vm_size         = "Standard_B1s"
}

build {
  sources = [
    "source.amazon-ebs.web-server",
    "source.azure-arm.web-server"
  ]

  provisioner "ansible" {
    playbook_file = "./web-server.yml"
  }
}

Provisioner Seçenekleri

Shell provisioner en basit yöntem; bash scriptleri veya inline komutlarla çalışır. Ansible provisioner, mevcut Ansible playbook'larını doğrudan kullanır ve karmaşık konfigürasyonları yönetilebilir kılar. Chef, Puppet ve Salt provisioner'ları bu araçları zaten kullanan ekipler için uygundur. File provisioner dosya kopyalama işlemi yapar; local dosyaları VM içine taşır. Windows ortamlar için PowerShell ve Windows Shell provisioner'ları mevcuttur.

Provisioner'ların çalışma sırası önemlidir. Birden fazla provisioner varsa sırayla yürütülür. Her provisioner VM'e SSH veya WinRM ile bağlanarak komut çalıştırır. Bağlantı parametreleri source bloğunda tanımlanır; özel key kullanımı, port ayarları ve timeout değerleri burada belirlenir.

Değişkenler ve Koşullu Mantık

HCL2'nin sunduğu değişken sistemi template'leri esnek kılar. Variable blokları ile input değerleri tanımlanır, build sırasında -var veya -var-file ile değerler aktarılır. Locals bloğu hesaplanan değerler için kullanılır. Conditional ifadeler ve for döngüleri ile dinamik konfigürasyonlar oluşturulabilir. Örneğin farklı region'lar için farklı AMI ID'leri tanımlanabilir veya debug modu aktifken ek provisioner'lar çalıştırılabilir.

Pipeline ve CI/CD Entegrasyonu

Packer, CI/CD pipeline'larına doğrudan entegre edilir. GitLab CI, Jenkins, GitHub Actions veya Terraform Cloud ile birlikte kullanılabilir. Image oluşturma süreci tamamen otomatik olduğundan, her commit sonrası güncel image üretilebilir. Bu yaklaşım immutable infrastructure prensibini destekler; her deployment yeni bir image üzerinden yapılır, mevcut VM'ler üzerinde değişiklik yapılmaz.

Best Practices

Image boyutunu minimal tutmak önemlidir; gereksiz paketler kurulmamalı, temizlik komutları provisioner'ların sonunda çalıştırılmalıdır. Provisioner'ı mümkün olduğunca az tutmak gerekir; çok sayıda küçük script yerine az sayıda kapsamlı script tercih edilmelidir. Image versiyonlama için timestamp veya git commit hash kullanılmalı, böylece hangi konfigürasyonun hangi image'e karşılık geldiği takip edilebilir olmalıdır. Sensitive veriler (parolalar, tokenlar) environment variable veya Vault entegrasyonu ile yönetilmeli, template içinde açık yazılmamalıdır.

Açık kaynak

GitHub projeleri

Tümünü gör
wireguard-server-panel

WireGuard VPN sunucu paneli - İstemci yönetimi, QR kodları ve trafik istatistikleri için kendi sunucunuzda barındırılan web kullanıcı arayüzü (fork, aktif olarak geliştirilmekte)

Go

Laravel-NDFirewall

Rota Kapsamlı Laravel WAF - RCE, SQLi, XSS ve SSRF algılama özelliklerine sahip hafif bir Web Uygulaması Güvenlik Duvarı

PHP

Trustsslroot

Tek komutla çalışan özel PKI oluşturucu - Kendi kendini imzalayan kök CA ve sertifikaları anında oluşturun

Go

node_exporter

Hafif sistem metrikleri aktarıcısı - Güvenli erişim kontrolüne sahip, Linux için durum bilgisi barındırmayan tek ikili dosyalı izleme hizmeti

Rust

ipReconary

IP keşif ve alt ağ analiz aracı - Hızlı ağ taraması ve IP istihbarat toplama

Rust

Cloudfiltred

Cloudflare IP beyaz liste güvenlik duvarı - 80/443 numaralı bağlantı noktalarını yalnızca Cloudflare IP’leriyle sınırlayarak kaynak sunucunuzu doğrudan saldırılara karşı koruyun

Rust

LoadAlertTracker

Hafif sistem yükü izleme arka plan programı - Eşik değerleri aşıldığında Telegram, Discord ve Mattermost üzerinden gerçek zamanlı uyarılar

Rust

ctCertWatch

Sertifika Şeffaflığı günlüğü izleyicisi - Kimlik avı alan adlarını, marka taklitçiliğini ve yetkisiz SSL sertifikalarını gerçek zamanlı olarak tespit eder

Rust

DDNS-FW

Dinamik DNS Güvenlik Duvarı - DDNS aracılığıyla değişen IP adreslerini takip edin ve güvenli erişim kontrolü için güvenlik duvarı kurallarını otomatik olarak güncelleyin

Rust