AWS CDK ile Multi Stage ve Multi Account, Event-Driven Mimari Kurulumu

Azmi Mengü
Cloud Türkiye
Published in
6 min readApr 5, 2021

Bugün hep birlikte AWS Cloud üzerinde Infrastructure as Code (IaC) yaklaşımlarından biri olan AWS CDK aracı ile çoklu AWS hesabı ve çoklu uygulama ortamlarımızda -stage, test, prod- örnekleriyle birlikte basit bir event-driven mimariyi gerçekleyeceğiz.

AWS Lambda, SQS, SNS, Event Driven Architecture, AWS CDK
Sample Event-Driven Application

Bu uygulama canlı ortamlarda deneyimlebileceğimiz gibi bir satınalma işlemi yapıldıktan sonra kullanıcıya SMS, Email bildirimi gönderme, satınalmaya ait lojistik kaydı oluşturma ve satınalma içerisinde herhangi bir sepet indirimi var ise bunları kontrol edip gerekli aksiyonları almak üzerine kurgulanmıştır. Uygulama kaynak kodlarına buradaki Github linki üzerinden ulaşabilirsiniz.

Mevcut uygulama örneğimizde event-driven mimarilemeye uygun olarak AWS Cloud’un hizmete sunmuş olduğu AWS Lambda, Amazon SQS ve Amazon SNS ürünlerini kullanıyor olacağız. Bunlar haricinde Amazon S3, AWS Codebuild ve AWS CloudFormation servislerini ise yukarıda saymış olduğumuz ürün aileleri içerisinde aktif olarak kullanacağız. Bu ürünlerin tümüne kısaca değineceğiz ve ana odağımız olan AWS CDK ile geliştirme kısmında detaylarına iniyor olacağız.

AWS CDK

AWS CDK aracı AWS tarafından 11 Temmuz 2019 tarihinde, Infrastructure as code yaklaşımına uygun olarak genel kullanıma sunuldu.

Peki nedir bu IaC?
Altyapı ve mimarilerimizi modern yazılım dillerini kullanarak ya da IaC sağlayacının (bkz. Terraform) ilgili yazım syntax’ına uyarak yazdığımız kodların derlenmesi ve bu derlemenin hangi Cloud sağlayıcıya uygun olmasını istiyorsak ona özel “template” yani şablonlar üreterek, ilgili Cloud sistemlerindeki kaynakları otomatik olarak yaratmamıza olanak sağlayan pratiklerdir.

Örnek olarak bu yazımızda kullanacağımız AWS CDK aracı için arkaplanda olup biten döngüyü aşağıdaki görselde görebiliriz.

AWS CDK, AWS, CloudFormation, Infrastructure as Code
AWS CDK Lifecycle

Bu arada AWS CDK’nın bizlere sağlamış olduğu komutlardan ikisini açıklayalım.

  1. $ cdk synth
    “Synthesize” yani sentezleme işlemi gerçekleştirerek yazdığımız kodlama dillerindeki (Typescript, Javascript, Python, Java, C#) yapıları “template” olarak derlememize yarayan komuttur.
  2. $ cdk deploy
    Derlenen şablonların, CloudFormation servisi üzerinde stack yaratımına olanak sağlayan komuttur.

Daha detaylı bilgi ve AWS CDK kurulumu için bu dökümana başvurabilirsiniz.

Her şey hazırsa örnek mimarimi üzerinden birlikte geçelim.

Burada “Async invocation” işlemiyle tetiklediğimiz, “check-out” adında bir Lambda fonksiyonumuz var. Bu fonksiyonu tetikleme işlemi için “Event” tipinde bir “invocation” yani çağrı işlemi yapıyoruz.

Fonksiyonumuzu bu şekilde tetiklememizin bir sebebi var. Lambda fonksiyonları “Async” ve “Sync” olarak iki tipte çağrı türüyle çağrılabilmektedir. Event bazlı bir uygulama üzerinde koştuğumuz için çağrımızı “Async” olarak gerçekleştirecek ve bu çağrı sonundaki başarılı işlemlerle birlikte diğer kullandığımız servislere yine “Async” bir şekilde event mesajlarımız gönderiliyor olacaktır. Sync-Async çağrılarla ilgili daha detaylı bilgi için bu dökümana göz atabilirsiniz.

AWS Lambda, SQS, SNS, Event Driven Architecture, AWS CDK
Sample Event-Driven Application

İlgili “Async” çağrı başarılı olduğu durumda “order-check-out-success-topic” adındaki SNS topic’ine ilgili mesajı iletiyor olacak.

Bu topic’e bağlı “create-delivery” ve “discount-checker” adında ise iki farklı “topic subscriber” yani burdaki bildirim sistemine gelen mesajları dinleyerek otomatik olarak tetiklenen fonksiyon aboneliklerimiz bulunmakta.

İlgili SNS topic’i aynı zamanda “send-email” ve “send-sms” fonksiyonlarını besleyecek olan, “order-completed-email-queue” ve “order-completed-sms-queue” adında iki farklı SQS kuyruğuna mesaj iletimi yapmakta. Bu işleme Fanout yani yayma işlemi diyoruz. Bu sayede SNS’e gelen herhangi bir event mesajının N tane farklı hedefe aktarımı bu SNS kaynağına abonelik oluşturularak gerçekleştirilebiliyor. Merak edenler için bu konuyla ilgili detaylı bilgiler aşağıdaki dökümanlarda bulunabilir.

Fanout to Amazon SQS queues
Common SNS Fanout scenarios

Son olarak yukarıda bahsetmiş olduğumuz “send email” ve “send sms” fonksiyonları ilgili iki farklı SQS kuyruk sistemine bağlı olarak, bu kuyruğa mesaj geldiğinde tetiklenecek biçimde ayarlanmıştır.

Kullanılan Diğer Kaynaklar

İlgili mimariyi gerçeklemek için kullandığımız diğer kaynaklar ve neden kullanıldığı ile ilgili açıklamaları yapalım.

  1. AWS Codebuild
    Bu servis CI pipeline’ı için Lambda kodumuza ait ilgili paket bağımlıklıklarını yüklemek, kaynak kodu derlemek ve Lambda deployment’ı gerçekleştirebilmek için gerekli “artifact” dosyalarımızı oluşturmak amacıyla kullanılmıştır.
  2. Simple Storage Service (S3)
    S3 servisini Lambda kaynak kodlarının “artifact” dosyalarını saklamak ve deployment anında Lambda kod kaynağını beslemek amacıyla kullanılmıştır.
  3. CloudFormation
    AWS üzerinde oluşturulacak ilgili “stack” çıktılarını, yaratımını ve düzenleme işlemlerini görüntüleyeceğimiz servis. AWS CDK aracı ilgili kaynakların AWS Cloud üzerinde işlem görmesi için CloudFormation servisini kullanmaktadır.

AWS CDK çoklu ortam ve çoklu hesap tanımlamaları

Bu kısımda çoklu ortam ve çoklu AWS hesabı kurulumu nasıl gerçekleştirdiğimiz kod üzerinde anlatalım.

Kaynak kodunu paylaştığımız bu yapı üzerinde bulunan “cdk.context.json” bize kod içerisindeki değişkenleri tanımlamamız için yardımcı olmakta.

Hazırladığımız yardımcı “getAppEnv” ve “getConfig” fonksiyonlarıyla ise çoklu ortam ve çoklu AWS hesabı desteğini, belirttiğimiz değerlerle ilgili kurulumu gerçekleştirmek için kullanıyoruz. Detaylı açıklamaya kaynak kod içerisindeki “README” dosyasından erişilebilir.

İlgili bu tanımlamalar sayesinde, örneğin S3 bucket kaynağımızı “eu-central-1” bölgesinde ve “prod” ortamı için yaratmak istersek “APP_ENV” değerini kodumuzu derlerken parametre olarak vererek ve “cdk.context.json” dosyası içerisindeki “account”, “region” bilgilerini buna bağlı olarak değiştirirsek sağlamış olacağız.

Bu “context” dosyasına kod içerisinde kullanmak istediğiniz herhangi bir sabiti verebilirsiniz.
Örneğin bu mimaride kullanılanacak olan Lambda fonksiyonlarının memory tanımlarını bu dosyada tutabilir ve fonksiyon classs’larında ilgili değerleri okuyarak, çeşitli ortamlardaki fonksiyonlarınızın memory değeri yönetimini gerçekleştirebilirsiniz.

Kaynak kodun README dosyasında da bulunan bazı komut satırlarını yine burada açıklayalım.

Örneğin bir Codebuild kaynağını yaratmak için aşağıdaki komut satırı çalıştırılır.

* cdk synth — app “npx ts-node bin/codebuild.ts” CheckoutFunctionCodebuildStack-dev

Bu komut satırı uygulamanın “bin” klasöründeki “codebuild.ts” dosyası içerisinde bulunan CheckoutFunctionCodebuildStack kaynağını sonunda bulunan “-dev” tanımıyla birlikte development ortamınız için ilgili kodu derler.

* cdk deploy — app “npx ts-node bin/codebuild.ts” CheckoutFunctionCodebuildStack-dev

Bu komut ile de Codebuild kaynağımız belirtilen development ortamı ve AWS hesabında yaratılır.

AWS Cloud, CodeBuild, Infrastructure as Code, AWS CDK
Codebuild Sample Projects

Tüm Codebuild kaynakları yaratıldıktan sonra ilgili uygulama ortamınız için yukarıdaki görseldeki gibi bir çıktı görmeniz gerekmektedir.

Bununla birlikte README dosyasındaki adımları uyguladığınız taktirde bir S3 kaynağıda öncesinde yaratılmış olacaktır. Şimdi birlikte bir Lambda fonksiyonu için gerekli “artifact” yaratımına geçelim.

* aws codebuild start-build — project-name dev-checkout-lambda — environment-variables-override “[{\”name\”:\”LAMBDA_VERSION\”,\”value\”:\”1.0.0\”}]”`

Bu komut satırı yardımıyla birlikte CodeBuild projemizde tanımlı olan S3 kaynağına “check-out” fonksiyonumuz için “artifact” yaratıyor olacağız. Artifact ismini belirtilen LAMBDA_VERSION ortam değişkeninden almaktadır. Başarılı bir build işlemi aşağıdaki görselde olduğu gibi görülebilir.

AWS CDK, Infrastructure as Code, CodeBuild, AWS Cloud
Codebuild Sample Logs

Daha sonrasında S3 bucket kaynağına ulaşıp ilgili “artifact” çıktısını görüntüleyebiliriz.

S3, AWS Cloud, Infrasturcure as Code, AWS CDK, Lambda artifact
S3 Sample Lambda Artifacts

Artık Lambda fonksiyonumuzu deploy etmek için hazırız.

* TAG=1.0.0 cdk synth — app “npx ts-node bin/function.ts” CheckoutFunctionStack-dev

* TAG=1.0.0 cdk deploy — app “npx ts-node bin/function.ts” CheckoutFunctionStack-dev

Bu iki komutu kullanarak “check-out” fonksiyonumuzu deploy ediyoruz. TAG değişkeninize ilgili fonksiyon için yarattığınız “artifact” ismini vermeniz gerekmektedir.

Bu bağlantı arka tarafda CodeBuild aracılığıyla oluşturduğumuz ve S3 servisi üzerinde sakladığımız “artifact” dosyalarını Lambda deployment’ı için kullanmamıza olanak sağlar.

Bu adımları izleyerek ve README dosyasındaki ilgili işlemlerin tümünü tamamladıktan sonra “check-out” fonksiyonumuzu “Async” olarak tetikledikten sonra tüm akışı “CloudWatch” üzerinde ya da ilgili servislerin “Monitoring” sekmelerinden izleyebilirsiniz.

Son olarak bir Lambda fonksiyonunu “Async” bir şekilde tetiklemek için gerekli komut satırı örneğini de aşağıya bırakalım.

* aws lambda invoke — function-name dev-checkout-function — invocation-type Event — payload ‘{ “AWS”: ‘ome’ }’ response.json

AWS Lambda, Amazon SNS, Infrastructure as Code, AWS CDK
Sample Function with SNS Destination
AWS Lambda, Amazon SQS, Infrastructure as Code, AWS CDK
Sample Function with SQS Trigger

Yazı içeriğinde bulunan tüm kaynak kod için buradaki Github link’ine ulaşabilirsiniz.

--

--