Continuous Delivery ve Deployment Pipeline Nedir ?

Continuous Delivery: Geliştirilmekte olan bir yazılımın; kısa aralıklarla, güvenilir ve hızlı bir şekilde, her istenildiği zamanda ürünleştirilmesini önemseyen bir yazılım mühendisliği yaklaşımıdır. Yazılımın building, testing ve releasing evrelerini olabildiğince hızlı ve sık olmasını sağlayarak; yazılımın production ortamına taşınması sürecinde; zamandan, risklerden ve diğer maaliyetlerinden tasarruf etmeyi hedefler.

Deployment Pipeline: Continuous Delivery yaklaşımının en merkezi noktası deployment pipeline‘dır. Geliştirilmekte olan bir yazılımın; geliştirilmeye başlandığı ilk andan, son kullanıcıya hizmet verecek noktaya gelene kadar gerçekleşecek olan tüm evrelerin otomasyonudur.

Atlassian Bitbucket Pipelines

Bitbucket Atlassian’ın, git ve mercurial tabanlı versiyon kontrol çözümleri sunduğu bir servisidir. Bitbucket Pipelines ise; 3. parti bir servise ihtiyaç duymaksızın, Continuous Delivery tasarlamanıza olanak sağlayan ve Bitbucket servisi ile entegre bir şekilde çalışan Deployment Pipeline aracıdır.

Temel çalışma prensibi ve ücretlendirme Kod reposunda gerçekleşen her push işleminden sonra, Bitbucket Pipelines bir docker container’ı ayağa kaldırır ve bu kod reposunu, ayağa kaldırmış olduğu container içersinde hazır eder. Ardından verilen yönergelere göre işlemleri yerine getirir. Tüm bu süreçte nasıl davranacağını(yönergeleri), pipelines entegrasyonu aktif edilmiş olan kod reponun içinde, ana dizinde bulunan bir konfigürasyon dosyasından anlar. (bitbucket-pipelines.yml)

Atlassian ücretlendirmeyi ayağa kaldırdığı container’ın çalışma süresi üzerinden hesaplar. Bir kullanıcı hesabı için 5 kişiye özel kod reposu hakkı verir ve aylık 50 dakika ücret ödemeden Pipelines servisini kullanmanıza olanak sağlar.

Pipelines Hello World

İlk yapılması gereken şey; reponun ayarlar sekmesinden Pipelines ayarlarını bulup Enable Pipelines ayarını aktif hale getirmek. Bu ayarı aktif hale getirmek için kod reposunda admin yetkiniz olmalı.

Ardından konfigürasyon dosyasını yazıp kod reponun ana dizinine atmamiz gerekiyor. Eğer istersek bu dosyayı Bitbucket web arayüzünden online olarak oluşturabilir yada düzenleyebiliriz.

Örnek olarak elimizde ruby ile geliştirilen bir jekyll uygulaması olsun. Pipelines konfigurasyon dosyam şu şekilde olacak;

bitbucket-pipelines.yml

image: ruby:2.4.0

pipelines:
  default:
    - step:
        script:
          # cevre degiskenleri
          - export TARGET_DIR="/srv/www/benim_sitem/"
          # gereklilikleri kur
          - bundle install
          - bundle exec jekyll build
          # uygulamayi paket haline getir
          - tar cvfJ site.tar.gz -C ./_site .
          # paketi sunucuya gonder
          - scp $COMMIT_ID.tar.gz deployuser@uzaktaki_sunucu:/tmp/
          # uygulamayi deploy et
          - ssh deployuser@uzaktaki_sunucu "tar xvf /tmp/$COMMIT_ID.tar.gz -C /srv/www/benim_sitem/releases/"
          - ssh deployuser@uzaktaki_sunucu "ln -sf $TARGET_DIR/releases/$COMMIT_ID $TARGET_DIR/current"
          - ssh deployuserr@uzaktaki_sunucu "sudo systemctl reload nginx"       
image: ruby:2.4.0

image direktifi bitbucket pipelines’ın docker container’ın hangi imajdan ayağa kalkacağını belirtiyor.

pipelines:
  default:
    - step:

pipelines direktifi ise tüm pipeline tanımlamalarını başlatıyor.

default; kod reposunda her push işleminden sonra çalışacak olan adımları başlatıyor, bitbucket pipelines repoya gelen her push için pipelines direktifinin altındaki adımları izleyecek.

step ise; içersinde kod repomuzun bir clonu olan docker container’ı ayaklandırıyor.

script:
  # cevre degiskenleri
  - export TARGET_DIR="/srv/www/benim_sitem/"

Bu örnek için olayın sonu ve aslında bir çok işlemi tamamladığımız yer ise script; yani container içersinde çalışacak olan bash komutları. Bitbucket Pipelines şuan için sadece GNU/Linux container’larını destekliyor. İlk adım olarak sunucuda uygulamanın olacağı hedef dizinini bir bash değişkeni olarak belirttim.

# gereklilikleri kur
- bundle install
- bundle exec jekyll build

Ardından jeklly paketini yükleyip build işlemini gerçekleştirdim.

# uygulamayi paket haline getir
- tar cvfJ site.tar.gz -C ./_site .
# paketi sunucuya gonder
- scp $COMMIT_ID.tar.gz deployuser@uzaktaki_sunucu:/tmp/

tar ile paketleyip ssh ile uygulamayı sunucuya gönderdim.

# uygulamayi deploy et
- ssh deployuser@uzaktaki_sunucu "tar xvf /tmp/$COMMIT_ID.tar.gz -C /srv/www/benim_sitem/releases/"
- ssh deployuser@uzaktaki_sunucu "ln -sf $TARGET_DIR/releases/$COMMIT_ID $TARGET_DIR/current"
- ssh deployuserr@uzaktaki_sunucu "sudo systemctl reload nginx"    

Sonrasında sunucuda sürümleri tuttuğum dizine uygulamayı açıp, bu dizini(son sürümü) nginx‘in baktığı, yani uygulamanın çalıştığı dizine linkledim. Ardından nginx servisini reload ettim ve deploy süreci tamamlanmış oldu.

Bu noktada dikkat etmemiz gereken konulardan biri; ssh bağlantısı için uzaktaki_sunucu‘nun fingerprint‘ini bitbucket pipelines’ın ayağa kaldıracağı container’ın known_host dosyasına eklemem lazım ki; ssh bağlantı sırasında bana “bu sunucunun fingerprint‘i bende yok ekleyim mi? “ diye sormasın. İnteraktif bir şekilde çalışmıyor pipelines. İkincisi; uzaktaki_sunucu‘ya deploy_user ile bitbucket pipelines’ın ayağa kaldıracağı container’ın içinden login olabilmem için bir anahtar çiftine ihtiyacım var. Sebebi ise yine interaktif olmayacak şekilde süreci ilerletmek zorunda olmam (bu tek nedeni değil tabi ki).

Kod reposunun ayarlar sekmesinden Pipelines ayarlarını bulup ardından SSH Keys sekmesi içerisinden anahtar çiftimizi oluşturup uzaktaki sunucunun fingerprint‘i çekebiliyoruz. Bitbucket Pipelines oluşturmuş olduğumuz anahtar çiftini ve uzaktaki sunucunun fingerprint’ini, ayağa kaldıracağı container’da gerekli yerlere ekliyor.

Artık Pipelines entegrasyonunun aktif edildiği kod reposuna gelen her push işlemi ile birlikte yukarıda yazmış olduğumuz direktifler çerçevesinde işlemler gerçekleşecektir. Tüm pipelines süreçlerini Pipelines sekmesinden takip edebilirsiniz. İşlemleri durdurabilir, tekrar başlatabilir, detaylı bir şekilde bilgi alabilirsiniz.

Modern yazılım geliştirme yaklaşımlarından biri olan Continuous Delivery’yi ve bu yaklaşımın kilit noktası Deployment Pipeline’ı Atlassian’ın Bitbucket Pipelines aracını kullanarak anlatmaya çalıştım. Bu yazıda; Bitbucket Pipelines’ın ne olduğunu, bir kod reposuna nasıl entegre edilebileceğini, Bitbucket Pipelines’a nasıl yönerge verilebileceğini giriş seviyesinde anlatmaya çalıştım. Yazının ikinci bölümünde; Bitbucket Pipelines’da değişkenler, cache mekanizmaları, branch lere göre build gibi ileri seviye konuları anlatmaya çalışacağım.