Merhaba,
Bu içeriğimizde, geliştiricilerin AWS kaynaklarını programlama dilleriyle tanımlayarak yönetmelerine olanak tanıyan bir yazılım geliştirme paketi olan AWS Cloud Development Kit(AWS CDK)‘i inceleyeceğiz. Tabi her şeyden önce bu paketi bizlere sunan davranışın temelleri olan Infrastructure as Code (IaC) kavramına temas ederek yola çıkacak ve burada ilk olarak bir farkındalık doğurduktan sonra AWS CDK ile tanışacağız. O halde fazla uzatmaksızın buyurun başlayalım.
Infrastructure as Code (IaC) Nedir?
Infrastructure as Code (IaC), bir altyapının(ki bu altyapıda sunucular, ağlar, veritabanları, depolama alanları vs. hepsi olabilir) geleneksel olarak manuel ayarlanmasına karşın programlanabilir kod olarak yönetilmesini ve yapılandırılmasını ifade eden bir kavramdır. IaC ile süreç tekrarlanabilecek ve versiyonlanabilecek şekilde otomatikleştirilebilmektedir.
IaC’nin en büyük avantajı, oluşturulmuş bir altyapının farklı cloud provider’ları yahut veri merkezleri üzerinde benzer şekilde kurulabilir olması yani taşınabilirliği sağlamasıdır.
IaC sayesinde altyapıyı dakikalar içerisinde kurma ve yönetme olanağı elde edebilmekte, environment’ları manuel yapılandırma süreçlerinde yaşanılan olası hata durumları mümkün mertebe ortadan kaldırılmakta, ihtiyaca binaen altyapı değişiklikleri versiyonlanarak kolayca izlenebilmekte ve böylece tüm süreci ister orta isterse de büyük ölçekli olsun tüm altyapılarda kolay ve merkezi bir şekilde yönetebilme olanağı elde edilebilmektedir.
Evet… anlayacağınız, IaC altyapı kaynaklarını programatik bir şekilde yönetmemizi sağlayacak olan devrim niteliğinde bir yaklaşımdır diyebiliriz.
AWS CDK Nedir?
AWS CDK, AWS tarafından sunulan bir IaC framework’üdür.
Malumunuz, geleneksel yöntemlerde AWS altyapısı genellikle JSON yahut YAML tabanlı CloudFormation şablonlarıyla tanımlanırken AWS CDK ile bu kaynaklar TypeScript, JavaScript, Python, Java ve C# gibi yüksek seviyeli programlama dilleri kullanılarak oluşturulabilmektedir.
AWS CDK’nın Amacı Nedir?
AWS CDK’nın temel amacı, AWS altyapısını kod olarak tanımlayarak infrastructure yönetimini yazılım geliştirme süreçlerine entegre etmek ve geliştiricilerin altyapı oluşturmalarını daha hızlı ve verimli hale getirmektir.
AWS CDK’nın Avantajları Nelerdir?
AWS CDK’nın sağladığı başlıca avantajları şöyle sıralayabiliriz;
- Kod Tabanlı Altyapı Tanımı
Altyapı kaynakları yüksek seviyeli programlama dilleriyle tanımlanabilmekte ve böylece geliştiriciler daha az karmaşıklıkla ve daha okunabilir şekilde altyapı oluşturabilmektedirler. - Yeniden Kullanılabilir Yapılar
Altyapı bileşenleri kod olarak tanımlandığı için modüler yapılar oluşturulabilir ve farklı projelerde yeniden kullanılabilir halde tasarımda bulunabilir. - CloudFormation İle Uyumlu
AWS CDK ile yazılan kodlar arka planda CloudFormation şablonlarına dönüştürülür ve AWS’ye uygulanır. Böylece CloudFormation’ın sağladığı tüm güvenlik ve yapılandırma yönetimi özelliklerinden yararlanılır. - Yüksek Düzeyli Soyutlama
AWS CDK, düşük seviyeli AWS kaynaklarını soyutlayarak daha kullanıcı dostu ve verimli kaynak yönetimi sağlar. Örneğin, sadece birkaç satır kod ile bir Lambda fonksiyonu ve ona bağlı bir API Gateway oluşturulabilir. - Sürükleyici Yazılım Geliştirme Deneyimi
IDE’ler ve kod tamamlama gibi araçlar AWS CDK ile kolayca entegre edilebilir. Bu da geliştiricilere daha hızlı bir geliştirme deneyimi sunar.
Yani anlaşılan AWS CDK’in nimetleri o kadar fazladır ki, özellikle benim gibi kompleks AWS cloud arayüzünde emekli emmiler gibi problem yaşayan geliştiriciler için soyutlama sağlayarak sevdiği ortam olan kod diyarından pratik bir şekilde altyapıları standardize edebilmesine ve yönetebilmesine imkan tanımaktadır.
AWS CDK Nasıl Kullanılır?
AWS CDK’nın kullanımı için öncelikle ilgili bilgisayara AWS CDK CLI‘ın yüklenmesi gerekmektedir. Bunun için aşağıdaki talimatın terminal üzerinden verilmesi yeterlidir;
npm install -g aws-cdkAWS CDK CLI’ın kurulumunu gerçekleştirdikten sonra AWS ortamının başlatılması ve gerekli ön hazırlıkların yapılması gerekmektedir. Bunun için de aşağıdaki talimatın verilmesi gerekmektedir;
cdk bootstrapBu komutun her yeni AWS hesabı için bir kez çalıştırılması yeterli olacaktır. Ha hala neden bu komutu çalıştırmamız gerektiğine dair bir fikriniz yoksa şöyle izah etmeye çalışalım. AWS CDK ile oluşturduğunuz kaynaklar, arka planda AWS kaynaklarını tanımlamak ve yönetmek için kod tabanlı şablon imkanı sağlayan CloudFormation servisi, AWS üzerinde çalıştırılırlar. Ancak bazı CDK projeleri, ki özellikle de Lambda, S3 Bucket, ECR (Elastic Container Registry) gibi kaynakları kullanacak projeler kendi kendini referans alabilen kaynakları oluştururlar. Bu kaynakların AWS’de deploy edilebilmesi için önceden bir ‘bootstrap’ işlemi yapılması gerekmektedir. cdk bootstrap komutu bu kaynakları hazırlayarak ortamı deploy sürecine uygun hale getirmektedir. (Kendi kendine erişim ya da referans alabilmekten kasıt; AWS CDK’nın AWS üzerinde deploy etmek istediği Lambda vs. gibi kaynakları önce kendi ortamına yükleyip oradan yönetmesi gerektiği durumlara karşılık gelmektedir. Misal olarak, bir Lambda fonksiyonunu AWS’ye yükleyebilmek için öncelikle S3 gibi bir depolama hizmeti yüklenmelidir. AWS CDK bu Lambda kodunu AWS’ye göndermeden önce kendi oluşturduğu S3 bucket’a yükler. Bu bucket, kendi kendine erişim kavramı için kullanılan bir varlıktır ve CloudFormation şablonu, Lambda fonksiyonunu oluştururken bu S3 bucket’tan alacak ve kullanacaktır.)
Ayrıca bu komut, CloudFormation stack’lerini ve Lambda gibi diğer varlıkları yüklemek için gerekli S3 bucket’i oluşturacak ve AWS CDK’nin CloudFormation stack’lerini deploy edebilmesi için ihtiyaç duyacağı izinlere sahip IAM rollerini oluşturacaktır. Böylece AWS kaynaklarının kendi kendine erişim ve kaynak yükleme gereksinimi olduğu bu tarz durumlarda bir ön hazırlık adımı gerçekleştirilmiş olunacaktır.
Velhasıl, ilgili talimat verildikten sonra varsayılan AWS profili neyse onun üzerinden çalıştırılacaktır.
cdk bootstrap aws://<AWS_ACCOUNT_ID>/<AWS_REGION>Tabi bir yandan CDK Bootstrapping sürecinin bir parçası olarak hangi AWS kaynaklarının deploy edildiğini bilmek isterseniz AWS CloudFormation üzerinden CDKToolkit stack’ine aşağıdaki gibi göz atabilirsiniz.
cdk init --language csharp talimatından yararlanılmaktadır.
Burada ilk olarak dikkat edilmesini istediğim husus, CDK projesi hangi dizinde oluşturuluyorsa projenin solution’ının ve içerisindeki bazı dosyaların isimlerinin oradan gelmesidir. Dikkat ederseniz CdkDotnetDevelopersStack.cs dosyası bu şekilde oluşturulmuştur. Bu dosya esasında default CloudFormation Stack’ine karşılık gelmektedir ve içeriği ilk etapta aşağıdaki gibidir;
using Amazon.CDK;
using Constructs;
namespace CdkDotnetDevelopers
{
public class CdkDotnetDevelopersStack : Stack
{
internal CdkDotnetDevelopersStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
// The code that defines your stack goes here
}
}
}
GlobalSuppressions.cs dosyası ise projedeki statik analiz uyarılarını bastırmak için kullanılmaktadır. Bu ne demek hocam? diye soruyorsanız şöyle izah edelim: C# projelerinde statik kod analiz araçları, potansiyel sorunlar ve stil hataları için uyarılar verebilmektedir. Bizlerin bu tür uyarıları belirli kod parçaları için görmezden gelmesi amacıyla GlobalSuppressions.cs dosyası kullanılır. Bu dosyanın içeriği genellikle otomatik olarak oluşturulur ve uyarıların hangi kod bölümleri için bastırılacağını belirtir. İçeriği ilk etapta aşağıdaki gibidir;
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Potential Code Quality Issues", "RECS0026:Possible unassigned object created by 'new'", Justification = "Constructs add themselves to the scope in which they are created")]
Proje yapılandırmanıza göre bu dosya boş olabilir yahut belirli uyarılar için özel suppress işlemleri barındırabilir.
Program.cs dosyasına gelirsek eğer adından da anlaşılacağı üzere AWS CDK projesinin giriş noktasıdır ve CDK uygulamasının başlatılmasından sorumludur. Program.cs dosyasında, CDK’nın çalıştırılması ve tanımlanan stack’lerin deploy edilmesi gibi işlemler yapılır. İlk etaptaki içeriği yorumlardan arındırıldıktan sonra aşağıdaki gibidir;
using Amazon.CDK;
namespace CdkDotnetDevelopers
{
sealed class Program
{
public static void Main(string[] args)
{
var app = new App();
new CdkDotnetDevelopersStack(app, "CdkDotnetDevelopersStack", new StackProps
{
});
app.Synth();
}
}
}
Burada yapılan çalışmayı özetlememiz gerekirse; App nesnesi, AWS CDK uygulamasını temsil etmekte ve tüm stack’lerin ve kaynakların bu uygulama içerisinde tanımlanmasını sağlamaktadır. new CdkDotnetDevelopersStack(app, "CdkDotnetDevelopersStack", new StackProps {}) tanımı ise stack’in oluşturulmasını sağlamaktadır. app.Synth() komutu ise AWS CloudFormation için daha sonra AWS’ye gönderilerek kaynakların oluşturulmasını sağlayacak olan bir template üretmektedir.
C# Kullanarak Bir AWS S3 Bucket’ı Oluşturma
Şimdi ilk olarak basit bir AWS S3 Bucket’ı oluşturarak devam edelim;
using Amazon.CDK;
using Amazon.CDK.AWS.S3;
using Constructs;
namespace CdkDotnetDevelopers
{
public class CdkDotnetDevelopersStack : Stack
{
internal CdkDotnetDevelopersStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
var s3Bucket = new Bucket(this, "example-bucket", new BucketProps
{
Versioned = false,
AutoDeleteObjects = true,
RemovalPolicy = RemovalPolicy.SNAPSHOT
});
new CfnOutput(this, "BucketArn", new CfnOutputProps { Value = s3Bucket.BucketArn });
}
}
}
Yukarıdaki çalışmaya göz atarsak eğer, new Bucket(..) komutuyla bir depolama birimi olan “example-bucket” isminde bir S3 bucket nesnesi oluşturulmaktadır. Oluşturulan bu bucket’ı yapılandırmak için BucketProps nesnesi kullanılmakta ve Versioned property’sine ‘false’ değeri verilerek versiyonlama devre dışı bırakılmaktadır. Böylece aynı isimle yüklenecek olan yeni dosyalar, eskilerin üzerine yazılacaktır. RemovalPolicy property’si ile de bucket’ın silinmesi durumunda ne yapılacağı belirlenmektedir. Burada ‘RemovalPolicy.SNAPSHOT’ değeri verilerek bucket silindiği taktirde bir snapshot alınması ve böylece verilerin korunması yapılandırılmıştır.
new CfnOutput(..) kodunda ise stack’te oluşturulan kaynakların kimi özelliklerinin çıktısı alınmaktadır. Ki böylece bu stack’te oluşturulan kaynak bilgileri diğer stack’ler yahut hizmetler tarafından rahatlıkla erişilebilsin ve kullanılabilsin.
Velhasıl, bu çalışmayı yaptıktan sonra stack’i deploy etmemiz yeterli olacaktır. Bunun için aşağıdaki talimatın verilmesi yeterlidir;
cdk deployBu talimatın verilmesi neticesinde bir ihtimal aşağıdaki gibi bir hatayla karşılaşılabilmesi muhtemeldir;RemovalPolicy.SNAPSHOT kullanımını desteklememesi ve bunun yerine RemovalPolicy.DESTROY ya da RemovalPolicy.RETAIN‘in kullanılması gerekliliğidir. Olası hatayla karşılaştığınız taktirde gerekli düzenlemeleri yapıp tekrardan ilgili talimatı verirseniz aşağıdaki gibi deploy’un başarıyla tamamlandığını gözlemleyebilirsiniz.
Resource Yapılandırmasında Güncelleme Yapmak
Ya bir resource yapılandırmasında güncelleme yapmak isteseydik? Misal olarak, S3 bucket’ta versiyonlamayı(Versioned) etkinleştirmek istiyor olsaydık… Bunun için yapılması gereken CDK koduna gerekli güncellemenin yansıtılması ve ardından bu güncelleme neticesinde mevcut olanla farkı yakalamak için cdk diff talimatının verilmesidir. Bu talimat bizlere CloudFormation’da deploy edilmiş stack’le, yeni yapılan değişiklik arasındaki farkı verecektir.
.
.
.
var s3Bucket = new Bucket(this, "example-bucket", new BucketProps
{
Versioned = true,
AutoDeleteObjects = true,
RemovalPolicy = RemovalPolicy.DESTROY
});
.
.
.
C# Kullanarak Bir AWS DynamoDB Tablosu Oluşturma
Şimdi de başka bir örnek yapalım. Bir CDK projesi üzerinden AWS DynamoDB tablosu oluşturalım.
using Amazon.CDK;
using Amazon.CDK.AWS.DynamoDB;
using Amazon.CDK.AWS.S3;
using Constructs;
namespace CdkDotnetDevelopers
{
public class CdkDotnetDevelopersStack : Stack
{
internal CdkDotnetDevelopersStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
#region Bucket - S3
.
.
.
#endregion
#region Table - DynamoDB
var dynamoDBTable = new Table(this, "example-table", new TableProps
{
TableName = "example-table",
PartitionKey = new Attribute { Name = "id", Type = AttributeType.STRING },
BillingMode = BillingMode.PAY_PER_REQUEST
});
new CfnOutput(this, "TableArn", new CfnOutputProps { Value = dynamoDBTable.TableArn });
#endregion
}
}
}
Burada yapılan çalışmayı incelersek eğer Table sınıfı ile ‘example-table’ adında bir DynamoDB tablosu tasarlanmakta ve PartitionKey property’si üzerinden ‘id’ adında string bir primary key alanı oluşturulmaktadır. Ayrıca BillingMode propery’si sayesinde de faturalandırma modeli olarak ‘BillingMode.PAY_PER_REQUEST’ değeri seçilerek yalnızca okuma ve yazma istekleri için ücretlendirme yapılandırılmasında bulunulmaktadır. Bu faturalandırma politikası için küçük ve düzensiz veri akışı olan uygulamalar için en ideal ve ekonomik seçenektir diyebiliriz.
Velhasıl, yapılan bu çalışmanın deploy edilebilmesi için cdk deploy talimatının verilmesi gerekmektedir.
C# Kullanarak Bir AWS Lambda’yı Deploy Etme
Ee hadi gelin son olarak da CDK üzerinden AWS Lambda’nın da deploy edilmesini inceleyerek içeriğimizi nihayete erdirelim. Tabi dikkat ederseniz oluşturulması değil deploy edilmesi diyorum. Çünkü CDK üzerinden bir lambda’nın oluşturulması ve iş mantığının üretilmesi teknik olarak pek mümkün değildir. O yüzden öncelikle bizim lambda’yı bildiğimiz yöntemlerle oluşturmamız(bknz: .NET 7 – AWS Lambda İle Serverless Computing) ardından da bunu CDK ile deploy etmemiz gerekmektedir.
dotnet lambda package --configuration release --framework net6.0 --output-package releases/example-lambda.zip
using Amazon.CDK;
using Amazon.CDK.AWS.DynamoDB;
using Amazon.CDK.AWS.Lambda;
using Amazon.CDK.AWS.S3;
using Constructs;
namespace CdkDotnetDevelopers
{
public class CdkDotnetDevelopersStack : Stack
{
internal CdkDotnetDevelopersStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
#region Bucket - S3
.
.
.
#endregion
#region Table - DynamoDB
.
.
.
#endregion
#region Lambda
var lambdaFunction = new Function(this, "example-function", new FunctionProps
{
Runtime = Runtime.DOTNET_6,
Code = Code.FromAsset("./src/CdkDotnetDevelopers/releases/example-lambda.zip"),
Handler = "Example.Lambda.Project::Example.Lambda.Project.Function::FunctionHandler"
});
#endregion
}
}
}
ve cdk deploy talimatını vererek AWS’ye deploy edelim.
AWS Resource’lerini Destroy Etmek
Şu ana kadar oluşturduğumuz AWS resource’larının yaratabileceği olası ek maliyetlerden süreci törpüleyebilmek için tüm stack’i destroy etmemiz gerekecektir. Bunun için
cdk destroy talimatının verilmesi yeterlidir.
AWS Servislerine Karşılık Gelen CDK Sınıfları Listesi
Yazı boyunca AWS CDK’nın çeşitli AWS servislerini temsil eden sınıflar içerdiği malum… Şimdi gelin olası ihtiyaçlara karşın hangi servise hangi sınıfın karşılık geldiğini yazarak genel bir liste ortaya koyalım;
- Depolama Servisleri
- S3 (Simple Storage Service) :
Bucket - EBS (Elastic Block Store) :
CfnVolume,CfnSnapshot - EFS (Elastic File System) :
FileSystem
- S3 (Simple Storage Service) :
- Hesaplama Servisleri
- EC2 (Elastic Compute Cloud) :
Instance,Vpc,SecurityGroup,KeyPair,CfnVolume - ECS (Elastic Container Service) :
Cluster,TaskDefinition,Service - EKS (Elastic Kubernetes Service) :
Cluster - Lambda :
Function - Batch :
JobQueue,ComputeEnvironment
- EC2 (Elastic Compute Cloud) :
- Veritabanı Servisleri
- RDS (Relational Database Service) :
DatabaseInstance,DatabaseCluster - DynamoDB :
Table - ElastiCache :
CacheCluster - Neptune :
DatabaseCluster
- RDS (Relational Database Service) :
- Ağ ve İçerik Teslimi
- VPC (Virtual Private Cloud) :
Vpc,Subnet,InternetGateway,NatGateway,RouteTable - CloudFront :
Distribution - Route 53 :
HostedZone,RecordSet - API Gateway :
RestApi,HttpApi
- VPC (Virtual Private Cloud) :
- Güvenlik ve Kimlik Yönetimi
- IAM (Identity and Access Management) :
Role,User,Policy,Group - KMS (Key Management Service) :
Key
- IAM (Identity and Access Management) :
- Mesajlaşma Servisi
- SNS (Simple Notification Service) :
Topic - SQS (Simple Queue Service) :
Queue - EventBridge :
Rule
- SNS (Simple Notification Service) :
- Analitik ve Makine Öğrenimi
- Kinesis :
Stream - Glue :
Crawler,Database,Job - Redshift :
Cluster - SageMaker :
NotebookInstance,Model
- Kinesis :
- Yönetim ve Gözetim
- CloudWatch :
LogGroup,Alarm,Metric - CloudTrail :
Trail - Config :
ConfigurationRecorder,DeliveryChannel - Systems Manager (SSM) :
Parameter,Document
- CloudWatch :
- Dağıtım ve Geliştirme Araçları
- CodeCommit :
Repository - CodePipeline :
Pipeline - CodeBuild :
Project - CodeDeploy :
Application,DeploymentGroup
- CodeCommit :
- Diğer Servisler
- Elastic Beanstalk :
CfnApplication,CfnEnvironment - Step Functions :
StateMachine
- Elastic Beanstalk :
Her bir hizmet için bu sınıflar sayesinde AWS altyapısını kod yazarak kolayca yönetebilir ve özelleştirebilirsiniz.
Nihai olarak;
Böylece .NET Developer’lar için AWS CDK ile ilgili genel çerçevede incelemede bulunmuş ve kısmi örneklerle de temel yapılanmayı detaylandırarak pratiksel ele almış oluyoruz.
İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…
Not : Örnek çalışmaya aşağıdaki github adresinden erişebilirsiniz.
https://github.com/gncyyldz/AWS.CDK.Example
