[ ECS — XIII] CodePipeline ile ECS Fargate(Blue/Green Deployment)

Tahacan Atak
7 min readJan 10, 2022

--

Bu yazıda Blue/Green deployment kullanan yeni bir ECS Service oluşturup bir önceki yazımızdaki oluşturduğumuz pipeline’ı blue/green deployment’a uygun hale getireceğiz.

ECS servicelerinde blue/green deploymentin CodeDeploy servisi tarafından yönetildiğinden daha önce bahsetmiştik.

ECS service’imizi oluşturmadan önce CodeDeploy servisine erişim için gerek IAM Role oluşturarak başlayalım.

IAM Service’ine gidip daha önce yaptığımız gibi Create Role diyerek başlayalım.

İkinci adımda AWSCodeDeployRoleForECS policy’i ekleyerek CodeDeployServiceRole ismiyle IAM Role’ü oluşturalım.

Artık ECS Service’ini oluşturmak için hazırız. Oluşturduğumuz clustera gidip yeni bir ECS Service oluşturalım.

Birinci adımda diğer oluşturduğumuz ECS Service’lerden farklı olarak bu kez deployment tipini Blue/Green Deployment seçeceğiz.

İkinci adım Network ve Load Balancing adımı. Network ayarları daha önce oluşturduğumuz ECS Service’leri ile aynı. Yine default VPC ve public subnetleri seçiyoruz. Security group seçerken source olarak application load balancer’ın security group’u olan ecssample-service-seg isimli security group’u seçelim. (Bu adımı tekrar incelemek isteyen için ilgili yazı)

Load balancing adımında daha önceden oluşturduğumuz load balancerı seçelim. Rolling update deployment ile oluşturduğumuz ECS Service’e göre farklılıklar burda başlıyor.

Gelen trafiği uygulamamızın yeni versiyonuna yönlendirmeden önce test edebilmemiz için bir Test Listener Portu oluşturmamız gerekiyor. Test Listener portunu create new diyerek 8080 portunu oluşturalım. Bu ayar ile birlikte mevcut application load balancerın listenerlarına 8080 portu eklenecek.

Blue/Green dağıtımlar için iki adet target group gereklidir. Şu an load balancer’ın dinlediği iki adet (80 ve 8080) portumuz var. Additional Configurationda bu portlara birer adet target group ayarlamamız gerekli. 80 portu için daha önceden oluşturduğumuz fargate-tg isimli target group’u kullanabiliriz. 8080 test listener portu içinde fargate-BG-tg isimli bir target group oluşturalım.

Review adımına geçerek yeni ECS Service’imizi oluşturalım. Service’i oluşturduktan sonra açılan sayfada oluşturulan kaynakları görüntüleyebilirsiniz. Deployment sürecemizi yönetecek CodeDeploy servisinde bir application oluşturuldu. İlgili linke tıklayarak inceleyebilirsiniz.

Her biri aynı application load balancer’a kayıtlı, ancak farklı portları dinleyen iki adet target group oluşturduk. Mevcut application load balancer’a gidip listenerlara bir bakalım.

Target grouplarımız ayarladığımız 80 ve 8080 portunu dinliyor. Yukarıda işaretli kısımda bir uyarı gözünüze çarpmış olmalı. ECS Service’i oluştururken load balancera 8080 listenerını ekledik ama bu port load balancerın security group’unda inbound rule’da yer almıyor. Bu uyarı size bunu bildirir. Uyarıya tıklayarak load balancerın security group’una giderek 8080 portunu açalım.

Şu an oluşturduğumuz ECS Service’inde bir adet çalışan taskımız var ve bu task 80 portunu dinleyen fargate-tg isimli target group’a kayıtlı. Load balancer’ın DNS Name ile uygulamaya gittiğinizde arkada çalışan taskımız cevap verecektir. Fakat 8080 portunu dinleyen target group’a şu an için kayıtlı bir taskımız yok bu yüzden DNSName:8080 adresini ziyaret ettiğinizde 503 hatası dönecektir.

Dağıtım süreci başladığında yeni versiyonu çalıştıran task 8080 portunu dinleyen fargate-green-tg isimli target group’ta çalışmaya başlayacak ve ECS Service’ini oluştururken belirlediğimiz deployment stratejisine göre(CodeDeployDefault.ECSCanary10percent5Minutes) CodeDeploy servisi load balancera gelen trafiğin yüzde 10'u bu target group’a kaydırılacak. Sizde bu süreçte uygulamanızın yeni versiyonuna 8080 portundan erişip testleriniz gerçekleştirebilirsiniz.

Artık bir önceki yazımızda oluşturduğumuz pipeline’ı Blue/Green deploymenta uygun hale getirmeye başlayabiliriz.

Öncelikle CodeBuild servisinde bulunan build projemize gidip buildspec.yaml dosyamızı güncelleyelim.

ECS servisinde Blue/Green deployment ile birlikte sürece dahil olan 3 yeni dosyamız var. imageDetail.json, appspec.yml ve taskdef.json.

imageDetail.json dosyası, Amazon ECS image Url’i tanımlayan json tipinde bir dosyadır. Blue/Green deploymentlarda ECS ve CodeDeploy servisine ECR gibi bir repositoryden alınacak image’in bilgilerini sağlamak için bir imageDetail.json dosyası oluşturmanız gerekli. Bizde buildspec.yaml dosyasını imageDetail.json dosyasını oluşturacak şekilde yapılandırdık.

appspec.yaml dosyası, dağıtımları yönetmek için CodeDeploy tarafından kullanılır. Projenin kök dizininde aşağıdaki içeriğe sahip bir appspec.yaml dosyası oluşturun.<TASK_DEFINITION> değiştirmeyin. Bu değer, pipeline çalıştığında güncellenir.

Daha önceden zaten bir task definition oluşturmuştuk. Şimdi oluşturduğumuz taskdefinitiona gidin. Bir JSON editörü bulacaksınız, oradaki tüm metni kopyalayın

Kopyaladığınız metni proje kök dizininde taskdef.json isimli bir dosya oluşturup içine yapıştıralım. “image” değerini <IMAGE1_NAME> olarak değiştirelim.

Aşağıdaki git komutları ile değişiklikleri CodeCommit servisindeki repository’e gönderelim.

  • git status
  • git add .
  • git commit -m “added appspec.yaml & taskdef.json files”
  • git push (kullanıcı adı ve şifre daha önce indirdiğimiz credentials dosyasında mevcut.)

Son olarak bir önceki yazımızda oluşturduğumuz pipeline’a gerekli düzenlemelere başlayalım.

Build adımında düzenlememiz gereken yer Output Artifacts kısmı. Yukarıda buildspec.yaml dosyasını güncellediğimizde iki adet artifact çıktısı belirtmiştik. Bunlar DefinitionArtifact ve ImageArtifact. Definitions Artifact appspec.yaml ve taskdef.json dosyasından, ImageArtifact ise imageDetail.json dosyasından oluşuyor.

Build adımındaki output artifactleri bu şekilde tanımlayarak değişikliği kaydedelim.

Şimdi pipelinenın 3.adımı olan deploy adımını güncelleyelim.

Bu kısımda Deploy providerını ECS(Blue/Green) olarak değiştirmemiz gerekiyor. Bu değişiklik ile birlikte alt kısımda istenilen bilgilerinde değiştiğini göreceksiniz.
Build adımındaki tanımladığımız output artifactleri(DefinationArtifact ve ImageArtifact) bu kısımda input artifact olarak seçiyoruz. appspec.yaml ve tasdef.json dosyalarının DefinitionArtifact’te bulunduğunu aşağıdaki gibi tanımlayalım. CodeCommit servisindeki uygulamamızın repositoryine gönderdiğimiz taskdef.json dosyasında <IMAGE1_NAME> diye bir alan tanımlamıştık. Son kısımda da bu alana gelecek image Url’in ImageArtifact üzerinden alınacağını belirtiyoruz. Değişiklikleri kaydedelim.

Mutlu son :) blue/green deployment içinde CI/CD sürecinin tümünü tamamlamış olduk.

Gelin şimdi uygulamamıza yeni bir versiyon çıkarmış gibi bir değişiklik yapalım ve ECS servisinde Blue/Green deploymentin tüm adımlarını takip edelim.

CodeCommit servisindeki repositoryde Home/index.cshtml’de aşağıdaki gibi değişiklik yaparak CI/CD sürecini tetikleyelim.

Master branchindeki değişiklik ile birlikte pipelinenımız çalışmaya başladı. Deploy aşamasına geldiğinde details’dan deployment süreciyle değişiklikleri tek tek inceleyelim.

Step 1' de yeni versiyonun bulunduğu task çalışmaya başlar. Step 2 de trafiğin %10 yeni versiyonun bulunduğu taska kaydırılmıştır.

Tam bu aşamada load balancerin DNS Name adresinden 8080 portuna gidelim.

Gördüğünüz gibi yaptığımız değişiklikle yeni versiyonu bu porttan test edebiliyoruz. Eğer direk DNS Nameden erişseydiniz yani 80 portundan o zaman 10 istekten sadece birisi yeni versiyonun bulunduğu target group’a yönlendirilecekti.

Sizin için 80 portundan yeni versiyonu yakaladım :)

Normalde load balancerın 80 ve 8080 portunu dinleyen iki ayrı target group bulunuyordu. Dağıtım tam bu adımdayken listenerları incelerseniz 80 portunu dinleyen iki adet target group olduğunu görebilirsiniz. Bunun sebebi az önce bahsettiğimiz trafiğin %10 ‘unun yeni versiyonun çalıştığı taska yönlendirmesinden kaynaklı.

Step 3 aşamasında ise trafiğin %90'ı seçtiğimiz deployment stratejisine göre 5 dakika içinde yeni versiyona geçirilir. Aşağıdaki sürece geçtiğinizde artık trafiğin %100 yeni versiyona yönlendirilmiştir. Bu aşamada yeni versiyonunda her şey stabil, tüm testleriniz başarılı ise Terminate original task set diyerek bir saatlik bekleme sürecini atlayarak eski taskı sonlandırıp dağıtım sürecini bitirebilirsiniz. Diğer bir senaryo yeni versiyonda bir hata gördünüz ve eski versiyona geri dönmek istiyorsunuz onun içinde Stop and roll back deployment diyerek tüm trafiği tekrar eski versiyona yönlendirebilirsiniz.

Yine bu aşamada listenera tekrar bakarsanız artık 80 portunu yeni versiyonun bulunduğu target group’un dinlendiğini görüntüleyebilirsiniz.

Son olarak deployment sürecini ECS’ de oluşturduğumuz service’den de takip edebilirsiniz.

--

--