Codefiction Artık Serverless

Codefiction gibi bir komünitenin haliyle zaman içerisinde bir takım masrafları da oluşmaya başlıyor. Soundcloud hesabı, kullandığımız uygulamaların lisans ücretleri, domain masrafları derken bir de hosting için yıllık ücretler ödemek ister istemez zaman içerisinde etkisini göstermeye başlıyor. Bunun için başlattığımız patreon hesabımızda destekçilerimize bir çok farklı şekilde fayda sağlamaya çalışıyoruz ama bu ücretleri ne kadar küçültürsek yapmak istediğimiz etkinliklere o kadar çok zaman ve kaynak ayırabileceğimiz için alternatif çözümleri sürekli tartışıyoruz.

Bugün sunucu masraflarından AWS Lambda Free Tier sayesinde nasıl kurtulduğumuzu anlatmaya çalışacağım. Dolayısıyla bu yazıda ağırlıklı olarak Sunucusuz Mimari’nin bir uygulamasından bahsedeceğim, ama eğer daha fazla teorik bilgi almak istiyorsanız Deniz’in yazısına göz atabilirsiniz.

Peki nerede bu sunucular?

Sanırım başlangıçta en çok kafa karıştıran konulardan biri de bu. Aslında sunucular hala var, fakat bunları biz ihtiyaç duymadığımız zamanlarda kullanmıyoruz. Yani bir ihtiyaç oluştuğu anda oluşturuluyor ve işi tamamlandıktan sonra yeniden kayboluyorlar. Bizim durumumuzda iki ihtiyacımız vardı; Birincisi şu anda çok fazla olmayan ama ilerleyen zamanlarda artacağını düşündüğümüz sunucu taraflı taleplerimizin host edilmesi, ikincisi de statik web sayfamızı host edebileceğimiz bir alan.

Sunucu Taraflı Uygulamalar

Daha önce PHP ile yazdığımız ve Podcast RSS feed’lerini sayfamızda göstermemizi sağlayan API’yi mümkün olduğunca masrafsız bir şekilde host etmemiz gerekiyordu. Bunun için ilk aklımıza gelen çözüm Heroku oldu, ancak onun da free tier’da dyno’ların yarım saat talep almadığında otomatik olarak uyuması ve sonraki ilk taleple uyanırken 3–4 dakika gibi bir latency yaşaması fikri hoşumuza gitmedi. Bunun üzerine biz de alternatifleri araştırmaya başladık ve AWS Lambda kullanmakta karar verdik. Kararımızın arkasında bir kaç sebep var, bunlardan birincisi maliyetleri.

AWS Lambda Free Tier kapsamında ilk 1 milyon talep ücretsiz. Evet bedava! Daha da önemlisi bir yıl sonunda bedava kalmaya devam ediyor. Şu aşamada çok fazla trafik almasa da uygulamaya sokacağımız başka özelliklerle birlikte bu sayıyı aşmayı hedefliyoruz. Ancak o zaman da fiyatları gerçekten makul.

Eğer ilginizi çektiyse neler yaptığımızı anlatmaya başlayabilirim artık.

AWS CodeStar

Öncelikle bir amazon hesabı açtım, arkasından AWS CodeStart kullanarak yeni bir AWS Lambda projesi oluşturdum. Ekranın solundaki listeden Node.js ve AWS Lambda seçtiğiniz zaman karşınıza bir kaç tane farklı proje çıkıyor. Ben bunlardan Node.js uygulamasını seçtim. Ancak bunun yanında Alexa skill de oluşturabiliyorsunuz. Ama şimdilik Node.js uygulamasına odaklanalım. Bunun yanında C#, Java, Python ve Ruby seçeneklerini değerlendirmek isteyebilirsiniz.

Bunu yaptığınız zaman AWS size otomatik olarak bir kaç ürününü ön tanımlı bir şekilde kullandırıyor.

AWS CodeCommit, Github, Gitlab gibi ölçeklenebilir ve güvenli bir git repository çözümü. En önemli özelliği IAM entegrasyonunu destekliyor olması. Bu yüzden eğer kurumsal olarak AWS kullanıyorsanız AWS dışına çıkmadan merkezi bir kullanıcı yönetiminden faydalanabilirsiniz. Bu hizmet ilk 5 kullanıcıya kadar ücretsiz.

AWS CodeBuild, Kodunuzu gönderdikten sonra devreye giren ve testlerinizi, gerekli kurulumlarınızı yöneten bir AWS hizmeti. Aslında Build Pipeline’nınızı tanımlamanızı ve yönetmenizi sağlıyor. Bu da her ay 100 dakikaya kadar ücretsiz kullanabileceğiniz ücretsiz servislerden bir tanesi.

AWS CloudFormation, Uygulamalarınızı kurabilmeniz için gereken infrastructure’ı hazırlamanızı sağlayan AWS hizmeti. Bu hizmeti kullandığınız diğer kaynakların ücretini ödediğiniz sürece bedava kullanabiliyorsunuz. Bizim durumumuzda AWS Lambda kullandığımız için tüm kaynaklar ücretsizdi, ancak eğer CodeBuild ile hazırladığınız pipeline’da testlerinizi çalıştırmak için çalıştırdığınız sunucular ya da başka kaynaklar varsa bunları yönetmen için de kullanacağınız için dikkatli olmanızda fayda var.

Amazon CloudWatch, AWS üzerinde çalışan uygulama ve kaynaklarınızı gözlemlemek için kullanacağınız hizmet diyebiliriz. Bunun da ücretsiz bir planı var ve bana kalırsa bunun sınırları bir çok ihtiyacınızı giderecek seviyede.

Bana kalırsa AWS CodeStar’ın en güzel yanı bu parçaları size sunarken bunları alternatifleriyle değiştirebiliyor olmanız. Örneğin CodeCommit’i Github ile değiştirebiliyorsunuz. Böylece AWS akvaryumunun içinde hapis olmaktan da kurtulabiliyorsunuz. Ama bu başka bir yazının konusu olsa gerek.

Şimdi biraz da kodu inceleyelim, bunun için öncelikle codefiction/codefiction-tech-lambda repository’sine bakabilirsiniz. Burada CodeStart tarafından oluşturulan bir kaç tane dosya hakkında konuşmak istiyorum, daha sonra build pipeline’dan bahsedeceğim;

template.yml: Bu dosya Lambda fonksiyonumuzun nasıl özellikleri olacağını tanımlayan AWS Template dosyası. Bu bilgiler Serverless Application Model (SAM) denilen bir tanımı içerisinde barındırıyor ve bu bilgiler deployment sırasında AWS CloudFormation tarafından okunarak nasıl bir kaynak oluşturacağına karar veriyor.

HelloWorld: 
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs4.3
Role:
Fn::ImportValue: !Join [‘-’, [!Ref ‘ProjectId’, !Ref ‘AWS::Region’, ‘LambdaTrustRole’]]
Events:
GetEvent:
Type: Api
Properties:
Path: /
Method: get
PostEvent:
Type: Api
Properties:
Path: /
Method: post

Burada dikkat edilmesi gereken kısım Resource kısmı. Burada CloudFormation’a hazırlanacak olan Lambda fonksiyonu hakkında bilgiler veriyoruz. Yukarıdaki örnekte çalışacak Lambda fonksiyonunun nodejs 4.3 versiyonunu kullanacağını ve handler olarak index.js dosyasını kullanacağını söylüyoruz. Böylece bu fonksiyona gelen taleplerde bu AWS Lambda fonksiyonu bizim için index.js dosyasını çalıştırıyor ve fonksiyonumuz ayağa kalkmış oluyor. Bunun bir öncesinde gelen ilk taleple birlikte AWS CloudFormation bizim için bir container ayağa kaldırıyor ve bunu nasıl provision edeceğini yani fonksiyonumun çalışabilmesi için hangi kurulumların yapılması gerektiğini de biliyor. Dolayısıyla sunucumun nasıl kurulacağını dert etmekten ziyade hangi koşullarda çalışacağını düşünmem yetiyor.

Yeri gelmişken AWS Lambda’nın başka kullanım alanlarına da değinmekte fayda var tabi ki. Bizim örneğimizde biz sadece API Gateway kullandık ancak buna ek olarak bir lambda fonksiyonunu bir çok farklı olaya da bağlamanız mümkün, örneğin bir S3 Bucket’e dosya yüklendiğinde bunları işlemek isteyebilirsiniz ya da AWS Kinesis kullanıyorsanız oluşan bir stream sonucunda yine fonksiyonunuzu çalıştırabilirsiniz, bu durumda yine AWS Lambda kullanarak yukarıdaki kod parçasındaki Events kısmında bununla ilgili tanımlama yapmanız mümkün. Bununla ilgili dokümantasyon Amazon’un web sitesinde mevcut ancak bugün kısıtlı vaktimizde ben sadece API Gateway kullandığımızı varsaydım.

Dosyalardan başka bir tanesi de buildspec.yml. Bu dosya da AWS CodeStar’ın kullandığı ve projenizi nasıl deployment’a hazır hale getireceğini tanımladığı yer. Buradaki bilgileri kullanarak AWS CodeStar uygulamanızdan bir paket oluşturuyor ve bunu bir S3 Bucket içerisine yüklüyor. Bundan sonra da AWS CodeBuild bu paketi kullanarak testlerinizi çalıştırıp CloudFront üzerindeki tanımlarla test ortamlarınızı hazırlayabiliyor ve sonunda canlı ya da test ortamlarına kurulumlarınızı yapıyor. Ön tanımlı olan CodeBuild pipeline’ı aşağıdaki gibi oluyor, ve siz bunu, edit butonuna basarak, istediğiniz gibi düzenleyebiliyorsunuz kendi ihtiyacınıza göre bir pipeline tanımlayabiliyorsunuz.

Source tanımlanan kısım ilk oluşturduğunuzda CodeCommit oluyor ancak bunu örnekteki gibi GitHub ile değiştirebiliyorsunuz.

Build kısmında ise yukarıda bahsettiğim buildspec.yml dosyasında tanımlanan komutlar çalıştırılıyor ve bunlar bir S3 Bucket’a yükleniyor.

Deploy aşaması bizim durumumuzda çalışan son adım, yani GitHub üzerindeki repository’mizde bir Pull Request merge edildiğinde otomatik olarak canlı endpoint’e bir kurulum gerçekleştiriliyor. Bu aşamada birim test’lerinizi, entegrasyon testlerinizi çalıştıracağınız ortamları kurmanız ve kurulum sonrasında bu kaynakları yok ederek testlerden geçmiş uygulamanızı canlı sistemlere kurmanız mümkün. İsterseniz bu noktada birisinin onayını bekleyebilir ve ondan sonra kurulum işleminizi gerçekleştirebilirsiniz.

Statik Web Sayfaları

Uzun uzun sunucu taraflı uygulamaları anlattıktan sonra son aşamaya belki de bir çok kişi için en önemli olan kısma geçebiliriz. Öncelikle uygulamamızı taşırken fırsattan faydalanıp sitemizi de Angular’a geçirdik, böylece artık daha hızlı bir şekilde geliştirme yapmaya başlayabileceğiz. Angular uygulamamızın kodlarına ve testlerine de codefiction/codefiction-tech üzerinden ulaşabilirsiniz.

Sunucu taraflı değişiklikler kurulduktan sonra sadece statik içerik barındıran ön yüz uygulamamızı da bir yere kurmamız gerekiyordu, bunun için de başka bir AWS servisi olan S3 hizmetini kullandık. Bunu yaparken yeni bir bucket oluşturduk ve gerekli izinleri verdikten sonra tek sorunumuz sunucu tarafında yaptığımız gibi Continuous Integration sürecimizi implemente etmemizdi. Codefiction-tech için SemaphoreCI kullanıyoruz ve bu işlemi orada yapmak gerçekten çok kolay ve kendi web sitelerindeki dokümantasyon ile bunu çok detaylı bir şekilde anlatıyorlar.

Eğer böyle bir sistem kullanmıyorsanız s3cmd gibi araçlarla komut satırından bunu yönetebileceğiniz gibi yukarıdaki örnekte olduğu gibi AWS servislerini de kullanabilirsiniz.

Bu konuyla ilgili gelecek hafta podcast’te konuşacağız ancak sorularınız olursa Gitter kanalımıza ya da twitter hesabımıza bekliyoruz. Sevgiler!