AWS CodeBuild ve CodePipeline ile Continuous Delivery

aws
codebuild
codepipeline
cicd

(Fatih YARCI) #1

Yazılım geliştiren ekiplerin; Rapid Development ve DevOps metodolojilerini benimsemeleri, geliştirilen kodun sürekli, kolay ve otomatize bir şekilde, versiyon kontrol sisteminden canlı ortama gitmesini zorunlu kılıyor. AWS CodeBuild ve CodePipeline servisleri tam bu noktada bize kolay ve yönetilebilir bir Continuous Delivery sistemi kurma imkanı sağlıyor.

Bu yazıda GitHub’da saklanan bir yazılımın, AWS CodeBuild ve CodePipeline servisleri ile otomatik bir şekilde derlenmesini ve paketi deploy edecek servise teslim edilmesi sürecini anlatmaya çalışacağım.

AWS CodePipeline

AWS CodePipeline servisi; entegre etmiş olduğunuz kod deposundaki kodun derlenme/paketlenme (building/packaging) ve deploy servisine çıktı (artifact) verme (delivery) işlemlerini otomatikleştirir/yönetir.

“Get started” butonuna tıklayarak başlıyoruz.

Bu ekranda oluşturacağımız CodePipeline servisine isim veriyoruz. Ben örnek için “aws_codepipeline_demo” ismini kullanacağım.

İkinci adımda kodun bulunduğu depo sağlayıcısını seçiyoruz. Ben örnek için GitHub servisini kullanacağım.

“Connect to GitHub” butonu ile GitHub servisinde oturum açıp gerekli izinleri veriyorum.

İzinleri verdikten sonra yine aynı ekranda CodePipeline servisinin entegre edileceği kod deposunu ve branch ini seçiyorum.

AWS CodeBuild

Bir sonraki ekranda (3. adım) CodePipeline servisi bize kodu derleyecek olan servisi soruyor. Sağlayıcı olarak AWS CodeBuild servisini seçiyorum ve “Configure your project” kısmında “Create a new build project” ile yeni bir proje oluşturuyorum.

“Project Name” kısmına CodeBuild projesi için isim veriyoruz. Örnek için ben “aws_codebuild” i seçtim.

CodeDeploy servisi; CodePipeline ile belirlemiş olduğumuz kod deposunun branchine (örnek için master) merge yapıldığında, bizim belirlediğimiz bir docker imaji ile bir container açıp kodu deposundaki kodu icine kopyalayacak. Docker imajini belirtmek için “Environment image” sekmesinde “Specify a Docker image” seçeneğini işaretliyoruz.“Environment type” Linux, “Custom image type” ise “Other” seçenekleri ile dolduruyoruz. “Custom image ID” kısmına daha önceden hazirlamış ve DockerHub’a atmış olduğum imajın adresini veriyorum.

Son olarak altta sağda bulunan “Save build project” tıklıyorum. Böylelikle CodeBuild projemi oluşturmuş oluyorum.

AWS CodePipeline

Bir sonraki adımda CodePipeline bize kodu deploy edecek servisi soruyor. Bunun icin AWS CodeDeploy servisini kullanabilirsiniz. Ben bu örnek için deployment kullanmayacağım.

“No Deployment” ı seçip devam ediyorum.

Son adımda CodePipeline servisi için IAM Role oluşturuyoruz. “Create role” seçeneği ile role oluşturup CodePipeline projesini oluşturuyoruz.

AWS CodeBuild buildspec.yml dosyası

AWS CodeBuild servisi; bir docker container oluşturup kod reposundaki kodu içine klonladığında ne yapacağını kod reposunun içinde oluşturacağımız “buildspec.yml” dosyasından anlıyor. Kodun nasıl derleneceğini, paketlenmesi için hangi komutların çalışması gerektiğini bu dosya yazacağımız direktiflere göre anlayacak.

Örnek “buildspec.yml”:

version: 0.2

env:
  variables:
    JAVA_HOME: "/usr/lib/jvm/java-8-openjdk-amd64"

phases:
  install:
    commands:
      - echo Entered the install phase...
      - apt-get update -y
      - apt-get install -y maven
    finally:
      - echo This always runs even if the update or install command fails
  pre_build:
    commands:
      - echo Entered the pre_build phase...
      - docker login –u User –p $LOGIN_PASSWORD
    finally:
      - echo This always runs even if the login command fails
  build:
    commands:
      - echo Entered the build phase...
      - echo Build started on `date`
      - mvn install
    finally:
      - echo This always runs even if the install command fails
  post_build:
    commands:
      - echo Entered the post_build phase...
      - echo Build completed on `date`
artifacts:
  files:
    - target/messageUtil-1.0.jar
  discard-paths: yes
cache:
  paths:
    - '/root/.m2/**/*'

İlk satırda “buildspec.yml” dosyasının versiyonunu belirledik. Ardından env direktifi ile çalışacak olan container için Bash çevre değişkenleri belirledik.

phases: kısmında fazlar belirleyip, hangi komutların çalışacağını belirliyoruz.

phases:
  install:
    commands:
      - echo Entered the install phase...
      - apt-get update -y
      - apt-get install -y maven
    finally:
      - echo This always runs even if the update or install command fails

install fazında maven yüklemek için gerekli komutlar ve bilgi mesajları basan komutlar var. Diğer fazlar için ise gerekli komutları ihtiyacınıza göre belirleyebilirsiniz. mvn install, mvn package gibi.

  build:
    commands:
      - echo Entered the build phase...
      - echo Build started on `date`
      - mvn install
      - mvn package
artifacts:
  files:
    - target/messageUtil-1.0.jar
  discard-paths: yes

artifact kısmı ise build ile oluşacak uygulama paketinin nerde olacağını CodeBuild servisine söylediğimiz yer, eğer istersek CodePipeline servisi bu artifactı istediğimiz bir AWS S3 bucket ına yada AWS CodeDeploy servisine iletebiliyor.

cache:
  paths:
    - '/root/.m2/**/*'

Son olarak cache kısmı ise bağımlılık paketlerinin indirildiği dizini cacheliyor. Sonraki build lerde vakit kazanmak için.

Bu dosyayı ihtiyaçlarımız doğrultusunda hazırlayıp kod depomuzda master branche yolluyoruz. Bu branchde ki her merge işleminden sonra AWS CodePipeline servisi otomatik olarak bunu algılayacak ve AWS CodeBuild servisini build işlemi için tetikleyecek. AWS CodeBuild servisi, belirlediğimiz docker imajından bir container açıp kod reposunu bu containerın içine klonlayacak. Ardından buildspec.yml dosyası içersindeki direktifleri çalıştıracak.

CodePipeline sayfasında proje ismine tıklayarak, projeyi görebilir ve düzenleyebilirsiniz.

Bu örnekte AWS CodePipeline ve CodeDeploy servislerini kullanarak dakikalar içersinde Continious Delivery sistemi hazırlamış oldum. Kullanım örnekleri ve ileri seviye konular için AWS’nin sağlamış olduğu dökümanlara göz atabilirsiniz.