Yeni Nesil Geliştirme Mottosu: Geliştirdim, Paketledim, Gördüm

Aklıma bir proje fikri geldi, kapsam üzerine çok yoğunlaşmadan hızlıca fikri canlandırmak ve meşhur global köye bir hane olarak yazdırmak istiyorum.

Hosting almalıyım, şu anda Python geliştiriyorum ve Linux tercih etsem iyi olacak. Ya sonrasında .NET’e geçersem ve Windows üzerinde sunmak istersem? Projeyi paketleyelim, hosting firmasının sağladığı FTP bilgileri neredeydi? Projem fark yaratırsa mevcut paketim trafiği kaldırır mı? Projemdeki bağımlılıkları kolayca yükleyebilecek miyim?

Yukarıdaki sorular çok yabancı gelmedi değil mi? Çok da uzun sayılmayacak zaman kadar önce bu soruların tamamına cevap aramaya çalıştığımızı hatırlıyorum.

AWS, Microsoft Azure, Google Cloud Platform, Heroku gibi yapılar hayatımıza girdiği günden bu yana yukarıdaki soruların tamamı birer birer, bir daha hiç sorulmayacakmış gibi, hayatımızdan çıkıp gidiyor. Ben de ilk paragrafımdaki sorunuma geri dönüyorum ve bu soruları hiç sormadan fikrimi internet mecrasına hızlıca sunmak için kolları sıvıyorum:

Yol Haritası

Bir Python — Tornado uygulaması geliştireceğim, projemin CI süreçlerini Travis üzerinden geçirip, Amazon Web Services’in Elastic Beanstalk servisi ile de yayına sunacağım.

Tahmini bekleme süremiz: Yaklaşık 15 dakika.

Bunlar da neyin nesi?

Yukarıda kalın harflerle yazılı teknoloji ve ürünlere yabancı olan ve bu satırlara kadar zahmet edip gelen arkadaşlara, kendilerini kısaca tanıtmak istiyorum.

Python — Tornado Web Server

Python tabanlı; Friendfeed ekibi tarafından geliştirilen, FriendFeed’in Facebook’a katılmasından sonra Facebook geliştirme ekibine devredilen ve yaşamına devam eden bir web kütüphanesinden bahsediyoruz.

Oldukça güçlü, asenkron bir web sunucusu olarak karşımıza çıkıyor. Çok hızlı bir şekilde gelen istekleri kabul edip işleyen, long-lived bağlantıların yönetimini güvenli bir şekilde gerçekleştiren bu ürün ile ilgili daha önce yapmış olduğum sunumu referans gösterebilirim.

Travis CI

Daha önceki bir yazımda bahsettiğim, favori CI aracım. Github üzerinde tuttuğunuz repolar ile senkron bir şekilde çalışan bu araç ile Python, Ruby, .Net, PHP gibi favori dillerde kodlanmış yazılımların bir takım süreçlerden (test betiklerinin çalıştırılması, uygulamaların paketlenmesi, sunuculara deploy edilmesi, vs…) otomatik bir şekilde geçirilmesini sağlıyor.

AWS — Elastic Beanstalk

AWS’nin bir bulut hizmeti olarak karşımıza çıkan bu servis, geliştirdiğiniz uygulamaların çok hızlı bir şekilde deploy edilmesini ve oldukça kolay bir arayüz üzerinden yönetilmesini sağlıyor.

Yukarıdaki tanım, bir sözlük tanımı aslında. Bir geliştirici için gerçekten çok önemli bir servis olduğunu düşünüyorum. Neden? sorusuna cevap vermek gerekirse,

  • Sistem altyapısı ile ilgili hemen hemen tüm endişeleri çözen bir olgunluğa sahip. Kendini otomatik olarak ölçeklendirebiliyor (auto-scaling), yükün balans edilmesini sağlıyor (load-balancing), uygulamanın herhangi bir anında oluşan ya da sunucu tarafından gerçekleşen sorunları takip edip görüntüleyebiliyor (monitoring).
  • Uygulamanızın sağlıklı bir şekilde hayatına devam edebilmesini sağlıyor. T anında uygulamanın cevap veremez hale gelmesi durumunda, uygulamayı tekrar başlatıp hayatına devam etmesini sağlıyor.
  • EC2 instance’ını ayrı, S3 storage’ını ayrı, load-balance uygulamasını ayrı yönetmenize gerek kalmıyor. Tek bir pakette tamamı size sunulmuş durumda ve konfigürasyon ekranından bunları tek tek yönetebiliyorsunuz.
  • Docker desteği var. Container’larınızı direkt olarak servis üzerinden yayınlayabiliyorsunuz.
  • Yukarıda saydığım popüler dillerin tamamını servis edebilme yeteneğine sahip.
Burada küçük bir durum eleştirisi yapmakta fayda var. Aslında örneğimi .Net Core ile geliştirmek istiyordum ama yazının yayınlandığı tarih itibariyle Elastic Beanstalk servisi üzerinde .Net Core uygulamaları sadece Windows sunucular üzerinde taşınabilir durumda. Linux desteği gelmesini dört gözle bekliyorum.
  • Servisin tekil olarak bir ücretlendirme durumu yok. Oluşturduğu servislerin (EC2 instance, S3 Storage, vs…) ücretlendirme politikası üzerinden kümülatif bir fatura çıkartıyor. Free-tier olarak kullanmaya başladığınızı söylemeden geçmek doğru olmayacaktır.

Bununla birlikte çok önemli bir noktayı belirtmekte fayda var diye düşünüyorum. Elastic Beanstalk’ın ortam ve çevre birimleri otomatik yönetmesinin dezavantajlarından önemli bir tanesi “stateless” koşulu. Demek oluyor ki, uygulamanız kapatıp açıldığında, bir takım özellikleri değiştirildiğinde herhangi bir veri kaybından endişe etmiyor olmanız gerekli. Dolayısıyla mimariyi oluştururken, burada konuşlanacak uygulamayı bir köprü olarak tasarlamak doğru olacaktır.

Hadi başlayalım

Uygulamaya bu adresteki Github reposundan ulaşabilirsiniz.

Uygulamadaki klasör hiyerarşisi

Klasör hiyerarşisindeki kritik dosyaları açmakta fayda var diye düşünüyorum:

  • /scripts/create-aws-profile.sh: Bu dosyayı Travis üzerinde çalıştıracağız. Amacımız, Travis’teki deploy makinemizde bir AWS konfigürasyon dosyası oluşturmak. Bu dosya içerisinde ise Elastic Beanstalk’a bağlanmak için gerekli kullanıcı bilgilerini tutacağız. Dosyayı oluşturup işledikten sonra ise src klasörü altındaki uygulamamızı bu bilgiler ile servise deploy edeceğiz.
Tam bu noktada Travis’e kısaca geçiş yapıyoruz. Bildiğiniz üzere AWS IAM bilgileri gizli bilgiler. Bunları ne kod içerisinde ne de build loglarında görmemiz gerekli. Dolayısıyla bir environment variable olarak tanımlayacağız ($AWS_PUBLIC_KEY ve $AWS_PRIVATE_KEY). Aşağıdaki görsel, Travis’teki projenizin ayarlar ekranında alıntı:
  • /src/.ebextensions/python.config: src klasörü içerisinde uygulamamızın kaynak kodları bulunuyor. Bu dosyanın ise normal bir Tornado projesinde yer alması gerekmiyor. Dosya içerisindeki konfigürasyon, Elastic Beanstalk tarafından kullanılacak ve uygulamanın çalıştırılacak ana dosyasını üzerinde taşıyacak.
  • .travis.yml: Bu dosya ise Travis tarafından süreci yönetmek amaçlı kullanılıyor. Önemli kısmı ise install adımında belirtilen komut(lar). Bu komutlara göre Travis deploy makinesine “awsebcli” paketi kurulacak. Bu paket, komut satırı üzerinden Elastic Beanstalk’a deploy yapmamıza olanak sağlıyor. Kurulum sonrası ise PATH ortam değişkeni düzenleniyor. Bunun sebebi ise “eb” komutunu çalıştırabilmemize olanak sağlamak.

AWS Elastic Beanstalk Adımı

Öncelikle Elastic Beanstalk’a programatik olarak erişecek kullanıcımızı oluşturalım. Bunun için IAM servisine gidiyoruz, soldaki menüden “Users” menüsünü seçiyor ve açılan pencereden “Add User” butonuna tıklıyoruz.

İlk adımda kullanıcımıza bir ad vereceğiz. Burada istediğiniz gibi bir isim verebilirsiniz. Önemli olan kısım alt bloktaki Select AWS Access Type. Buradaki seçimimiz Programmatic Access olacak.

İkinci adımda ise izinleri belirliyoruz. Bu ekranda çıkan büyük butonlardan en sağdakini — Attach existing policies directly — seçeneğini seçiyoruz. Öntanımlı bir kural dizisi seçeceğiz. Bunun için aşağı doğru açılan ekrandaki otomatik tamamlama alanına beanstalk yazıyoruz ve gelen sonuçlardan AWSElasticBeanstalkFullAccess seçeneğini seçiyoruz:

Üçüncü adımdaki özet ekranında seçimlerimizi gözden geçiriyor ve dördüncü adımda bu kullanıcı için oluşturulan Access Key ID ve Secret Access Key değerlerini bir yere not ediyoruz.

Yukarıda not aldığımız değerler, Travis üzerinde oluşturduğumuz environment varible değerleri. Access Key ID olarak kopyaladığımız değeri $AWS_PUBLIC_KEY değişkenine, Secret Access Key değerini ise $AWS_PRIVATE_KEY değerine atamalısınız.

Artık Elastic Beanstalk servisimizi kullanmaya başlayabiliriz. Bunun için üst menüdeki Services menüsüne tıklıyoruz ve açılan pencereden Compute başlığı altındaki servisimizi seçiyoruz.

Servisi yeni aktif ettiğimiz için şu anda bir uygulama görünmüyor ancak açılan yeni sayfanın sağ üst kısmında “Create New Application” seçeneğini görüyor olmalısınız. Buna tıklayalım ve açılan pop-up ekranına uygulamamızın adını yazalım: tornado-sample-app

Oluşturduğumuz uygulamanın altında servis edeceğimiz ortamları tanımlayacağımız ekran şu anda karşımızda. “Create New One” linkine tıklıyoruz ve açılan pop-up’tan Web Server Environment seçeneğini işaretliyoruz.

Bu noktada yine belirtmekte fayda var ki; bu servis altında bir web uygulaması sunabileceğiniz gibi, bir worker uygulama da sunabilirsiniz.

Açılan konfigürasyon sayfasındaki tek ayarımız Platform alanındaki ayar olacak. Benim uygulamam bir Python uygulaması olduğu için bunu seçiyorum ancak aşağıda da göreceğiniz üzere bir çok platform desteği hali hazırda mevcut:

Son olarak uygun platformu seçip Create Environment butonuna basıyorum ve ortamımın hazırlanmasını bekliyorum. Dilerseniz burada Configure More Options butonuna basarak servisin yöneteceği değişkenlerin ön ayarlarını yapabilirsiniz. Ayrıca Application Code kısmındaki Upload butonunu kullanarak projenizi zip halinde direkt S3 servisine yükleyebilirsiniz (biz bu işlemi Travis üzerinden yapıyoruz).

Eğer her şey yolunda gitti ise repomuza bir commit yapalım ve Travis’in süreci yönetmesine izin verelim. Örnek olarak kullandığımız repoda herhangi bir sorun çıkmadı ve uygulamamız Elastic Beanstalk’a deploy edildi. Sonuçta aşağıdaki gibi bir ekranla karşılaştık:

Üst satırda yer alan URL ifadesinin karşısındaki adrese tıkladığımızda ise uygulamamızın capcanlı bir şekilde çalıştığını görebileceğiz:

Sonuç

Elastic Beanstalk servisinin kurcalanması gereken bir çok detayı var. Biz bu örnekte en basit haliyle, 15 dakikada, hayal ettiğimiz uygulamayı Almanya’daki arkadaşımıza göstermek istedik. Ayrıca Travis üzerinden de süreçleri detaylandırabiliriz. Tabii ki diğer dilleri ve dillere bağlı kütüphaneleri kullanarak uygulamalarımızı çeşitlendirebiliriz.

Sonuç olarak bu servis, hız ve maliyet olarak kazanımları yüksek seviyede nitelendirilebilir diye düşünüyorum.

Bir sonraki yazıya kadar geliştirmeleriniz hatasız, paketleriniz sorunsuz, yayınlarınız hep taze kalsın :)