Takip et

AWS CDK ile PostgreSQL + Bastion + VPC Dağıtımı: Kapsamlı Rehber

Modern yazılım geliştirme dünyasında, hızlı, güvenli ve tekrarlanabilir altyapı dağıtımı kritik bir öneme sahiptir. Manuel kurulumlar zaman alıcı olmanın yanı sıra hata yapma potansiyelini artırır ve özellikle büyük ölçekli projelerde sürdürülebilirliği zorlaştırır. Güvenlik açıkları, yapılandırma hataları ve uyumluluk sorunları gibi pek çok risk faktörü, manuel yaklaşımlarla ortaya çıkabilmektedir. Örneğin, bir geliştirici ekibinin her yeni ortam için aynı PostgreSQL veritabanını, Bastion host’u ve VPC’yi manuel olarak yapılandırmak zorunda kalması, hem verimliliği düşürür hem de farklı ortamlar arasında tutarsızlıklar yaratabilir. İşte tam da bu noktada, altyapıyı kod olarak (Infrastructure as Code – IaC) yönetme ihtiyacı doğar.

Bu kapsamlı rehberde, Amazon Web Services (AWS) Cloud Development Kit (CDK) ve Python programlama dilini kullanarak, güvenli ve ölçeklenebilir bir PostgreSQL veritabanı altyapısını nasıl otomatize edeceğimizi adım adım inceleyeceğiz. Bir Virtual Private Cloud (VPC) içinde izole edilmiş, bir Bastion host üzerinden güvenli erişim sağlayan ve AWS Relational Database Service (RDS) ile yönetilen bir PostgreSQL örneğini kuracağız. Bu yöntem, sadece altyapı dağıtımını hızlandırmakla kalmayacak, aynı zamanda güvenlik standartlarını yükseltecek ve maliyet kontrolünü kolaylaştıracaktır. Ayrıca, gerçek dünya senaryolarından örnekler vererek, bu mimarinin neden tercih edilmesi gerektiğini ve sağladığı avantajları detaylandıracağız. Son olarak, mobil uyumluluk ve SEO ipuçlarıyla bu makaleyi zenginleştirerek, siz değerli okuyucularımıza kapsamlı bir kaynak sunmayı hedefliyoruz. Bu rehberin sonunda, kendi AWS altyapınızı CDK ile güvenle yönetebilecek bilgi birikimine sahip olacaksınız.

Uzman İpucu: Altyapıyı kod olarak yönetmek, yalnızca dağıtımı hızlandırmakla kalmaz, aynı zamanda felaket kurtarma senaryolarında kurtarma süresini (RTO) önemli ölçüde kısaltır. Tüm altyapınızı dakikalar içinde yeniden ayağa kaldırabilirsiniz.

Neden AWS CDK ve Python Kullanmalıyız? Otomatik Altyapının Gücü

Modern bulut tabanlı uygulamalar, esneklik, ölçeklenebilirlik ve güvenlik gerektirir. Bu gereksinimleri karşılamak için altyapı yönetiminde devrim niteliğinde yaklaşımlara ihtiyaç duyulmaktadır. AWS CDK ve Python’ın bu alanda sunduğu avantajlar, geleneksel yöntemlere kıyasla önemli farklar yaratır. AWS CDK (Cloud Development Kit), altyapıyı tanıdık programlama dillerini (Python, TypeScript, Java, C#, Go) kullanarak tanımlamamıza olanak tanıyan açık kaynaklı bir yazılım geliştirme çerçevesidir. Geliştiricilerin kullandığı dillerle altyapıyı yazmak, hem öğrenme eğrisini azaltır hem de karmaşık mantıkları, koşullu yapıları ve döngüleri altyapı koduna entegre etmeyi kolaylaştırır. Örneğin, belirli bir ortam için (dev/test/prod) farklı boyutlarda veritabanları veya farklı güvenlik ayarları tanımlamak, CDK ile if-else blokları veya döngülerle çok daha basit hale gelir.

Python’ın CDK ile uyumu, bu güçlü aracı daha da erişilebilir kılar. Python’ın basit sözdizimi, geniş kütüphane ekosistemi ve yüksek okunabilirliği, altyapı kodunu yazmayı ve sürdürmeyi kolaylaştırır. Bir DevOps ekibi, zaten Python’ı otomasyon ve scripting için kullanıyorsa, CDK ile altyapı yönetimine geçiş yapmak oldukça doğal bir adımdır. Ayrıca, Python’ın zengin modül ve paket yapısı, CDK uygulamalarının daha modüler ve yeniden kullanılabilir olmasını sağlar. Bu sayede, aynı VPC yapısını birden fazla projede kullanmak veya farklı veritabanı yapılandırmalarını ayrı ayrı tanımlamak mümkündür.

AWS CDK’nın sağladığı bir diğer önemli fayda, yüksek seviyeli abstraksiyonlardır. CDK, AWS CloudFormation üzerinde çalışır ve altyapı kaynaklarını daha soyut bir şekilde tanımlamamıza olanak tanır. Örneğin, bir VPC oluşturmak için CloudFormation’da onlarca satır JSON veya YAML kodu yazmak yerine, CDK’da tek bir Python sınıfı çağırarak temel VPC yapısını oluşturabiliriz. Bu abstraksiyon, geliştiricilerin altyapı detaylarına boğulmadan iş mantığına odaklanmasına yardımcı olur. Ayrıca, CDK’nın güçlü hata yakalama ve doğrulama mekanizmaları, dağıtım öncesinde potansiyel sorunları tespit etmeyi kolaylaştırır. Bu durum, özellikle büyük ölçekli veya hassas projelerde zaman ve maliyet tasarrufu sağlar.

Gerçek dünya senaryolarında, bir startup’ın yeni bir ürün geliştirdiğini ve hızla pazara sürmesi gerektiğini düşünün. Manuel altyapı kurulumları haftalar sürebilir ve piyasaya çıkışı geciktirebilir. AWS CDK kullanarak, bir geliştirici veya DevOps mühendisi, birkaç gün içinde tüm temel altyapıyı (VPC, veritabanı, sunucular, yük dengeleyiciler vb.) kod olarak tanımlayabilir ve saniyeler içinde dağıtabilir. Bu, ürünün daha hızlı test edilmesini, geri bildirim alınmasını ve yinelemeli olarak geliştirilmesini sağlar. Ayrıca, bu yaklaşım maliyet kontrolüne de yardımcı olur; gereksiz kaynakların dağıtılmasını engeller ve sadece ihtiyaç duyulan kaynakların doğru boyutlarda kullanılmasını sağlar. Sonuç olarak, AWS CDK ve Python, modern bulut altyapısı yönetiminde verimlilik, güvenlik ve ölçeklenebilirlik açısından vazgeçilmez bir kombinasyon sunar.

Güvenli Bir Bulut Altyapısının Temel Taşları Nelerdir?

Bulut ortamında sağlam ve güvenli bir altyapı oluşturmak, uygulamanızın başarısı için hayati öneme sahiptir. Bu bölümde, güvenli bir bulut mimarisinin olmazsa olmaz bileşenlerini ve bunların neden kritik olduğunu inceleyeceğiz. Her bir bileşenin rolünü anlayarak, AWS CDK ile bu yapıları nasıl otomatize edeceğinizi daha iyi kavrayacaksınız.

VPC (Virtual Private Cloud) Nedir ve Neden Önemlidir?

VPC, AWS bulutunda sizin için ayrılmış, izole edilmiş sanal bir ağdır. Kendi veri merkezinizin AWS üzerindeki eşdeğeri gibi düşünebilirsiniz. VPC, ağ topolojinizi, IP adres aralıklarınızı, alt ağlarınızı (subnets), rota tablolarınızı ve ağ geçitlerinizi tamamen kontrol etmenizi sağlar. Bu izolasyon, uygulamanızın ve verilerinizin diğer AWS müşterilerinden tamamen ayrılmasını garanti eder. Bir VPC oluşturduğunuzda, bu, uygulamanız için kendi özel ve güvenli alanınızı inşa ettiğiniz anlamına gelir. İçindeki kaynaklar (EC2 örnekleri, RDS veritabanları vb.) sizin tanımladığınız kurallara göre iletişim kurar. Örneğin, hassas veritabanlarınızı genel internet erişiminden izole etmek için özel alt ağlarda (private subnets) barındırabilirsiniz. Bu alt ağlardaki kaynaklar, dışarıya doğrudan çıkış yapamazken, genellikle bir NAT Gateway üzerinden internete erişebilirler. Bu sayede, güvenlik yamaları indirme gibi işlemleri gerçekleştirebilirsiniz. Genel alt ağlar (public subnets) ise genellikle internete doğrudan erişebilen yük dengeleyiciler ve web sunucuları gibi kaynakları barındırır. Bu detaylı kontrol mekanizması, ağ tabanlı saldırılara karşı ilk savunma hattınızı oluşturur ve uyumluluk gereksinimlerini karşılamanıza yardımcı olur.

PostgreSQL RDS: Yönetilen Veritabanı Hizmetinin Avantajları Nelerdir?

Veritabanları, her uygulamanın kalbidir ve doğru yönetimi kritik öneme sahiptir. AWS Relational Database Service (RDS), bulutta ilişkisel veritabanlarını kurmayı, işletmeyi ve ölçeklendirmeyi kolaylaştıran yönetilen bir hizmettir. PostgreSQL, popülaritesi ve sağlamlığı nedeniyle birçok geliştiricinin tercihidir. RDS PostgreSQL’in en büyük avantajı, veritabanı yönetimiyle ilgili sıkıcı ve zaman alıcı görevleri (yedekleme, yama uygulama, yazılım yükseltmeleri, donanım tedariki, arıza tespiti ve kurtarma) AWS’nin üstlenmesidir. Bu sayede, geliştiriciler ve operasyon ekipleri, veritabanının altyapısı yerine uygulamanın kendisiyle ilgilenebilirler. RDS, otomatik yedeklemeler, anlık kurtarma noktaları ve yüksek erişilebilirlik için Multi-AZ (çoklu erişim bölgesi) dağıtımı gibi özellikler sunar. Multi-AZ dağıtımı, birincil veritabanı örneğiyle senkronize bir bekleme örneği oluşturarak, bir arıza durumunda otomatik devir teslimi sağlar ve uygulama kesintisini en aza indirir. Ayrıca, RDS veritabanlarını güvenlik gruplarıyla entegre etmek, ağ düzeyinde erişim kontrolünü kolaylaştırır ve yalnızca yetkili kaynakların veritabanınıza bağlanmasını sağlar. Bu özelliklerin tümü, hem operasyonel yükü azaltır hem de veritabanınızın sürekli olarak güvenli ve yüksek performanslı çalışmasını garanti eder.

Bastion Host: Güvenli Erişim Noktası Olarak Rolü Nedir?

Bastion host, bir ağın veya alt ağın güvenli bir giriş noktası olarak işlev gören özel bir sunucudur. Özellikle özel ağlarda (private subnets) bulunan kaynaklara (örneğin veritabanları veya uygulama sunucuları) doğrudan SSH veya RDP erişimi olmamasını sağlamak amacıyla kullanılır. Bunun yerine, tüm yönetim erişimi Bastion host üzerinden yönlendirilir. Bu yaklaşım, saldırı yüzeyini önemli ölçüde azaltır çünkü dış dünyadan erişilebilir tek bir sunucu noktası olur. Bir geliştiricinin veya yöneticinin özel alt ağdaki bir veritabanına bağlanması gerektiğinde, öncelikle genel alt ağda bulunan Bastion host’a SSH ile bağlanır ve ardından Bastion host üzerinden özel alt ağdaki hedefe tünel açar. Bu tünelleme mekanizması, doğrudan erişim yerine katmanlı bir güvenlik sağlar. Bastion host’un güvenlik grubu sıkı bir şekilde yapılandırılır ve yalnızca belirli IP adreslerinden (örneğin, şirket VPN’i veya güvenli bir ağ) SSH erişimine izin verilir. Bu katı erişim kontrolü, özel kaynaklarınızı potansiyel dış tehditlerden korumak için hayati bir adımdır. Ayrıca, Bastion host üzerindeki tüm erişim günlükleri tutularak denetim ve uyumluluk gereksinimleri de karşılanabilir.

Security Groups: Erişim Kontrolünün Temeli Nasıl Çalışır?

Güvenlik Grupları (Security Groups), AWS’deki sanal güvenlik duvarlarıdır. AWS kaynaklarına (EC2 örnekleri, RDS veritabanları, Yük Dengeleyiciler vb.) gelen ve giden ağ trafiğini kontrol ederler. Her bir güvenlik grubu, içinde “izin ver” kuralları tanımlanan bir dizi kural içerir. Güvenlik grupları durum bilgisini korur; yani, bir giden isteğe izin verilmişse, gelen yanıt trafiği de otomatik olarak izin alır. Bu, trafik akışını daha kolay yönetmenizi sağlar. Örneğin, bir web sunucusunun güvenlik grubuna sadece 80 (HTTP) ve 443 (HTTPS) portlarından gelen trafiğe izin verirken, Bastion host’un güvenlik grubuna yalnızca belirli bir IP adresinden 22 (SSH) portuna gelen trafiğe izin verebilirsiniz. Veritabanı örneğinizin güvenlik grubu ise sadece uygulama sunucularından veya Bastion host’tan gelen PostgreSQL portu (varsayılan 5432) trafiğine izin verecek şekilde yapılandırılmalıdır. Bu katmanlı güvenlik yaklaşımı, her bir kaynağın yalnızca ihtiyaç duyduğu erişime sahip olmasını sağlayarak yetkisiz erişim riskini en aza indirir. Güvenlik grupları, altyapınızın mikro-segmentasyonunu sağlamanın temel araçlarından biridir ve ağ güvenliğinizin en kritik bileşenlerinden biridir.

Adım Adım AWS CDK ile PostgreSQL, Bastion ve VPC Dağıtımı

Şimdi teoriden pratiğe geçme zamanı! Bu bölümde, AWS CDK ve Python kullanarak, güvenli bir PostgreSQL veritabanı, Bastion host ve VPC altyapısını adım adım nasıl dağıtacağımızı ele alacağız. Her adımı açıklayıcı kod örnekleriyle destekleyerek, kendi ortamınızda kolayca uygulayabilmenizi sağlayacağız. Başlamadan önce, AWS hesabınızın olduğundan ve AWS CLI’ın yapılandırıldığından emin olun.

Ortam Hazırlığı: CDK CLI ve Gerekli Kütüphaneler Nasıl Kurulur?

İlk olarak, sistemimizde AWS CDK CLI’ı ve gerekli Python kütüphanelerini kurmamız gerekiyor. Bu adımlar, CDK projemizi başlatmak ve AWS kaynaklarını tanımlamak için temel araçları sağlar.

Komut satırınızı açın ve aşağıdaki adımları uygulayın:

  1. Node.js ve NPM Kurulumu (CDK CLI için): AWS CDK CLI, Node.js tabanlıdır. Eğer sisteminizde yoksa, Node.js resmi web sitesinden kurulum yapın.
  2. AWS CDK CLI Kurulumu: NPM kullanarak CDK CLI’ı global olarak kurun:
    
    npm install -g aws-cdk
    

  3. Yeni Bir CDK Projesi Başlatma: Projeniz için bir dizin oluşturun ve içine girin, ardından Python şablonuyla yeni bir CDK uygulaması başlatın:
    
    mkdir cdk-postgres-bastion-vpc
    cd cdk-postgres-bastion-vpc
    cdk init app --language python
    


    Bu komut, app.py, cdk_postgres_bastion_vpc/cdk_postgres_bastion_vpc_stack.py ve requirements.txt gibi temel proje dosyalarını oluşturacaktır.

  4. Python Sanal Ortamını Oluşturma ve Kütüphaneleri Kurma: Proje dizininizde bir sanal ortam oluşturun ve gerekli Python paketlerini yükleyin.
    
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
    pip install aws-cdk.aws-ec2 aws-cdk.aws-rds aws-cdk.aws-secretsmanager
    


    Bu paketler, VPC, EC2 ve RDS kaynaklarını tanımlamak için gereklidir.

  5. AWS Hesabınızı Bootstraplama: CDK'nın kaynakları AWS hesabınızda dağıtabilmesi için bir kerelik bootstrapping işlemi yapmanız gerekir. Bu, CDK'nın durumunu yönetmek için gerekli S3 kovasını ve IAM rollerini oluşturur.
    
    cdk bootstrap
    


    Bu komut, AWS::CDK::Bootstrap adında bir CloudFormation yığını oluşturacaktır.

Artık ortamınız hazır! cdk_postgres_bastion_vpc/cdk_postgres_bastion_vpc_stack.py dosyasını düzenleyerek altyapınızı tanımlamaya başlayabiliriz.

VPC Oluşturma: Ağ Temellerini Atmak

Tüm kaynaklarımız için güvenli ve izole bir ağ ortamı sağlamak üzere bir VPC oluşturacağız. Bu VPC, hem genel (public) hem de özel (private) alt ağları içerecek ve NAT Gateway'ler aracılığıyla özel alt ağlardaki kaynakların internete çıkışını sağlayacaktır.


from aws_cdk import (
    Stack,
    aws_ec2 as ec2,
    aws_rds as rds,
    aws_secretsmanager as secretsmanager,
)
from constructs import Construct

class CdkPostgresBastionVpcStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # 1. VPC Oluşturma
        self.vpc = ec2.Vpc(self, "PostgresVPC",
            max_azs=2, # Yüksek erişilebilirlik için 2 Avaliability Zone
            cidr="10.0.0.0/16",
            # Public ve Private Subnet'leri tanımlama
            subnet_configuration=[
                ec2.SubnetConfiguration(
                    name="Public",
                    subnet_type=ec2.SubnetType.PUBLIC,
                    cidr_mask=24
                ),
                ec2.SubnetConfiguration(
                    name="Private",
                    subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS, # NAT Gateway ile internet erişimi
                    cidr_mask=24
                )
            ],
            nat_gateways=1 # Her AZ için bir NAT Gateway yerine tek bir tane kullanıyoruz
        )

        # Output VPC ID (İsteğe bağlı, ancak faydalıdır)
        # CfnOutput(self, "VPCId", value=self.vpc.vpc_id, description="The ID of the VPC")

Yukarıdaki kod bloğunda, ec2.Vpc yapıcısını kullanarak temel bir VPC oluşturuyoruz. max_azs=2 ile iki farklı Availability Zone'a yayılan alt ağlar oluşturulmasını sağlıyoruz. subnet_configuration, hem public hem de private alt ağları tanımlar. PRIVATE_WITH_EGRESS alt ağ tipi, özel alt ağdaki kaynakların NAT Gateway üzerinden internete erişebilmesini sağlar. Bu, örneğin işletim sistemi güncellemelerini indirmek için gereklidir ancak dışarıdan doğrudan erişime kapalı kalır. nat_gateways=1 ise maliyet etkinliği için tek bir NAT Gateway kullanmamızı sağlar. Bu yapı, uygulamamız için hem güvenlik hem de esneklik sunan sağlam bir ağ temeli oluşturur.

RDS PostgreSQL Veritabanı Kurulumu: Yönetilen Veri Depolama

Veritabanı, uygulamamızın can damarıdır. AWS RDS kullanarak yönetilen bir PostgreSQL veritabanı örneği oluşturacağız. Bu, yedekleme, yama ve ölçeklendirme gibi operasyonel yükleri AWS'ye bırakmamızı sağlar. Güvenlik için, veritabanı kimlik bilgilerini AWS Secrets Manager'da saklayacağız.


        # 2. RDS PostgreSQL Veritabanı Oluşturma
        # Veritabanı şifresi için AWS Secrets Manager kullanın
        db_credentials_secret = secretsmanager.Secret(self, "DBCredentialsSecret",
            secret_name="PostgresDbCredentials",
            generate_secret_string=secretsmanager.SecretStringGenerator(
                secret_string_template='{"username": "postgres"}',
                exclude_characters='@/"\'\\',
                password_length=16
            )
        )

        # Veritabanı Güvenlik Grubu (Sadece Bastion'dan erişim)
        db_security_group = ec2.SecurityGroup(self, "DbSecurityGroup",
            vpc=self.vpc,
            description="Allow access to Postgres RDS from Bastion Host",
            allow_all_outbound=True # Dışarıya çıkışa izin ver
        )
        # Gelen kuralı daha sonra Bastion'a bağlayacağız

        self.db_instance = rds.DatabaseInstance(self, "PostgresInstance",
            engine=rds.DatabaseInstanceEngine.postgres(version=rds.PostgresEngineVersion.VER_14),
            vpc=self.vpc,
            vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS),
            instance_type=ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MICRO),
            credentials=rds.Credentials.from_secret(db_credentials_secret),
            database_name="mydatabase",
            multi_az=False, # Geliştirme/test için tek AZ, üretim için True
            allocated_storage=20,
            allow_major_version_upgrade=False,
            auto_minor_version_upgrade=True,
            backup_retention=7, # 7 günlük yedekleme
            parameter_group=rds.ParameterGroup.from_parameter_group_name(self, "PostgresParamGroup",
                "default.postgres14"
            ),
            security_groups=[db_security_group],
            deletion_protection=False # Geliştirme/test için False, üretim için True
        )

Bu kısımda, öncelikle secretsmanager.Secret ile veritabanı kullanıcı adı ve parola için güvenli bir sır oluşturuyoruz. Parola otomatik olarak oluşturulur ve PostgresDbCredentials adıyla Secrets Manager'da saklanır. Ardından, veritabanı için bir güvenlik grubu (db_security_group) tanımlıyoruz. Bu güvenlik grubu, varsayılan olarak dışarıya tüm çıkışlara izin verir, ancak gelen trafiği henüz kısıtlamaz. rds.DatabaseInstance ile PostgreSQL veritabanı örneğini oluştururuz. Motor sürümünü (Postgres 14), VPC ve özel alt ağları belirtiriz. instance_type ile örnek boyutunu seçeriz. credentials parametresi ile Secrets Manager'daki sırrımızı bağlarız. multi_az=False geliştirme ortamları için maliyetten tasarruf sağlarken, üretim için True olarak ayarlanmalıdır. deletion_protection=False da benzer şekilde geliştirme ve test ortamlarında hızlı silme işlemleri için uygundur, ancak üretimde kesinlikle True olmalıdır.

Bastion Host Konfigürasyonu: Güvenli Ağ Geçidi

Özel alt ağdaki veritabanımıza güvenli bir şekilde bağlanabilmek için bir Bastion host kuracağız. Bu sunucu, public alt ağda yer alacak ve yalnızca belirli IP adreslerinden SSH erişimine izin verecektir.


        # 3. Bastion Host Oluşturma
        # Bastion Host için Güvenlik Grubu (Sadece SSH'a izin ver)
        bastion_security_group = ec2.SecurityGroup(self, "BastionSecurityGroup",
            vpc=self.vpc,
            description="Allow SSH access to Bastion Host",
            allow_all_outbound=True
        )
        # Sadece kendi IP adresinizden SSH'a izin verin (ÖRNEK: "0.0.0.0/0" yerine kendi IP adresinizi kullanın)
        bastion_security_group.add_ingress_rule(
            peer=ec2.Peer.any_ipv4(), # Kendi statik IP'nizi veya IP aralığınızı buraya yazın
            connection=ec2.Port.tcp(22),
            description="Allow SSH access from anywhere (UPDATE THIS!)"
        )
        # Örnek: ec2.Peer.ipv4("YOUR_PUBLIC_IP/32")

        # Bastion Host için AMI
        # En güncel Amazon Linux 2 AMI'sını seçin
        amzn_linux = ec2.MachineImage.latest_amazon_linux2()

        self.bastion_host = ec2.Instance(self, "BastionHost",
            vpc=self.vpc,
            instance_type=ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MICRO),
            machine_image=amzn_linux,
            vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC),
            security_group=bastion_security_group,
            key_name="your-ssh-key-name" # SSH anahtarınızın adını buraya yazın
        )
        # Output Bastion Public IP
        # CfnOutput(self, "BastionPublicIp", value=self.bastion_host.instance_public_ip, description="Bastion Host Public IP")

Bastion host için ayrı bir güvenlik grubu (bastion_security_group) oluşturulur. Bu güvenlik grubuna, sadece 22 numaralı SSH portundan gelen trafiğe izin veren bir kural eklenir. ec2.Peer.any_ipv4() yerine mutlaka kendi statik genel IP adresinizi veya IP aralığınızı belirtmelisiniz; aksi takdirde Bastion host internetteki herkese açık SSH erişimine maruz kalır. AMI (Amazon Machine Image) olarak en son Amazon Linux 2 kullanırız. ec2.Instance ile Bastion EC2 örneğini oluştururuz. vpc_subnets ile bu örneğin public alt ağda yer almasını sağlarız. key_name parametresi için AWS'de zaten oluşturulmuş bir SSH anahtarınızın adını girmelisiniz; bu anahtar olmadan Bastion host'a bağlanamazsınız.

Güvenlik Gruplarının İlişkilendirilmesi: Doğru İzinleri Belirleme

Şimdi en kritik güvenlik adımlarından birine geliyoruz: güvenlik gruplarını birbirine bağlamak. Bastion host'umuzun, PostgreSQL veritabanımıza erişmesine izin vermeliyiz, ancak bu erişim sadece Bastion host'tan gelmelidir.


        # 4. Güvenlik Gruplarını İlişkilendirme
        # Bastion host'tan RDS'e 5432 (PostgreSQL) portundan erişime izin ver
        db_security_group.add_ingress_rule(
            peer=self.bastion_host.connections.security_groups[0], # Bastion'ın güvenlik grubu
            connection=ec2.Port.tcp(5432),
            description="Allow PostgreSQL access from Bastion Host"
        )
        
        # Sonuç olarak, veritabanı sadece Bastion üzerinden erişilebilir olacak.

Bu kod bloğu, db_security_group'a yeni bir gelen kural ekler. peer olarak self.bastion_host.connections.security_groups[0] değerini kullanarak, bu kuralın yalnızca Bastion host'umuzun güvenlik grubundan gelen trafiğe uygulanmasını sağlarız. connection=ec2.Port.tcp(5432) ise PostgreSQL'in varsayılan portu olan 5432 üzerinden TCP trafiğine izin verir. Bu kural ile, sadece Bastion host üzerinden tünel açarak veritabanımıza güvenli bir şekilde bağlanabiliriz. Bu, doğrudan internetten veya diğer yetkisiz kaynaklardan gelen veritabanı erişimini tamamen engellediği için kritik bir güvenlik önlemidir.

CDK Uygulamasını Dağıtma: Koddan Buluta

Tüm altyapı kaynaklarımızı CDK ile tanımladık. Şimdi bu tanımı AWS hesabımıza dağıtma zamanı.

  1. Synthesize (Sentezleme): CDK kodunuzu AWS CloudFormation şablonlarına dönüştürmek için cdk synth komutunu kullanın. Bu, dağıtımdan önce oluşturulacak kaynakları görmenizi sağlar.
    
    cdk synth
    


    Bu komut, cdk.out dizininde CloudFormation şablonlarını oluşturur.

  2. Deploy (Dağıtma): Altyapınızı AWS hesabınıza dağıtmak için cdk deploy komutunu çalıştırın.
    
    cdk deploy
    


    CDK, CloudFormation yığınını oluşturacak ve tüm kaynakları sağlayacaktır. Bu işlem biraz zaman alabilir (özellikle RDS veritabanı kurulumu). Komut istemi sırasında AWS IAM yetkilendirmeleri hakkında bir onay isteyebilir; y yazarak onaylayın.

  3. Silme (Opsiyonel): Altyapınızı kaldırmak istediğinizde, cdk destroy komutunu kullanabilirsiniz.
    
    cdk destroy
    


    Bu komut, oluşturulan tüm AWS kaynaklarını geri alacaktır. Yine bir onay isteği gelecektir.

Bu adımları tamamladıktan sonra, AWS hesabınızda yeni bir VPC, içinde bir Bastion host ve özel bir alt ağda PostgreSQL veritabanı örneği başarıyla dağıtılmış olacaktır. Artık Bastion host üzerinden veritabanınıza güvenli bir şekilde bağlanabilir ve uygulamanızı geliştirmeye başlayabilirsiniz!

Gerçek Dünya Senaryoları ve İpuçları: CDK ile Optimizasyon

Altyapımızı AWS CDK ile başarılı bir şekilde dağıttık. Ancak, gerçek dünya senaryolarında sadece dağıtım yeterli değildir. Maliyet optimizasyonu, felaket kurtarma, kimlik bilgileri yönetimi ve sürekli entegrasyon/sürekli teslimat (CI/CD) gibi konular da büyük önem taşır. Bu bölümde, CDK ile bu alanlarda nasıl iyileştirmeler yapabileceğinize dair ipuçları ve gerçek dünya vaka analizleri sunacağız.

Maliyet Optimizasyonu: Geliştirme Ortamları için RDS Otomatik Durdurma/Başlatma

RDS veritabanları, özellikle geliştirme ve test ortamlarında sürekli çalışmak zorunda değildir. Geceleri veya hafta sonları kapalı kalmaları, önemli maliyet tasarrufu sağlayabilir. AWS CDK, bu tür bir otomasyonu dolaylı yoldan sağlamak için kullanılabilir. Direkt olarak bir RDS örneğini durdurup başlatma işlevini CDK kodunda tanımlayamasanız da, CDK ile bu işlemi tetikleyecek AWS Lambda fonksiyonları ve EventBridge kuralları oluşturabilirsiniz. Örneğin, her akşam belirli bir saatte RDS örneğini durduran ve sabah başlatan bir Lambda fonksiyonunu CDK ile dağıtabilirsiniz.


# aws_cdk.aws_lambda as lambda_, aws_events as events, aws_events_targets as targets
# ...
# Bu örnek, bir Lambda fonksiyonunu ve EventBridge kuralını CDK ile nasıl dağıtacağınızı gösterir.
# Lambda'nın RDS'i durdurup başlatması için gerekli IAM izinlerine sahip olması gerekir.

# Lambda fonksiyonunun kodu (Python)
lambda_code = """
import boto3
import os

def handler(event, context):
    rds = boto3.client('rds')
    db_instance_identifier = os.environ['DB_INSTANCE_IDENTIFIER']
    action = event['action'] # 'start' or 'stop'

    if action == 'stop':
        print(f"Stopping RDS instance: {db_instance_identifier}")
        rds.stop_db_instance(DBInstanceIdentifier=db_instance_identifier)
    elif action == 'start':
        print(f"Starting RDS instance: {db_instance_identifier}")
        rds.start_db_instance(DBInstanceIdentifier=db_instance_identifier)
    else:
        print(f"Unknown action: {action}")
"""

# Lambda Fonksiyonu Oluşturma
rds_scheduler_lambda = lambda_.Function(self, "RDSSchedulerLambda",
    runtime=lambda_.Runtime.PYTHON_3_9,
    handler="index.handler",
    code=lambda_.Code.from_inline(lambda_code),
    environment={
        "DB_INSTANCE_IDENTIFIER": self.db_instance.db_instance_identifier # Daha önce oluşturulan RDS'in ID'si
    }
    # IAM rolleri için gerekli izinleri burada eklemeniz gerekir (rds:StopDBInstance, rds:StartDBInstance)
)

# Durdurma için EventBridge Kuralı (Her akşam 19:00 UTC)
events.Rule(self, "StopRDSRule",
    schedule=events.Schedule.cron(minute="0", hour="19", day="*", month="*", year="*"),
    targets=[targets.LambdaFunction(rds_scheduler_lambda,
        event=events.RuleTargetInput.from_object({"action": "stop"})
    )]
)

# Başlatma için EventBridge Kuralı (Her sabah 07:00 UTC)
events.Rule(self, "StartRDSRule",
    schedule=events.Schedule.cron(minute="0", hour="7", day="*", month="*", year="*"),
    targets=[targets.LambdaFunction(rds_scheduler_lambda,
        event=events.RuleTargetInput.from_object({"action": "start"})
    )]
)

Bu yaklaşım, manuel müdahaleye gerek kalmadan maliyet tasarrufu sağlar. Özellikle yoğun mesai saatleri dışında veritabanı kullanımının az olduğu geliştirme ve test ortamları için idealdir. Bir e-ticaret şirketinin geliştirme ekibi, bu yöntemle her ay %30'a varan RDS maliyeti tasarrufu sağladığını fark etmiştir.

Uzman İpucu: Üretim ortamlarında RDS Multi-AZ kullanmak yüksek erişilebilirlik sağlarken, geliştirme/test ortamlarında tek AZ ve durdurma/başlatma otomasyonu maliyetleri düşürmenin anahtarıdır.

Felaket Kurtarma ve Yüksek Erişilebilirlik: Multi-AZ Yapısı

Üretim ortamlarında veri kaybı veya hizmet kesintisi kabul edilemezdir. AWS RDS'in Multi-AZ özelliği, birincil veritabanı örneğinizin farklı bir Availability Zone'da senkronize bir yedeğini tutarak yüksek erişilebilirlik ve felaket kurtarma sağlar. Birincil örnekte bir sorun olduğunda (donanım arızası, AZ kesintisi vb.), RDS otomatik olarak yedek örneğe devir teslim (failover) yapar. CDK ile bunu etkinleştirmek çok basittir:


# RDS oluştururken:
self.db_instance = rds.DatabaseInstance(self, "ProductionPostgresInstance",
    # ... diğer parametreler ...
    multi_az=True, # Üretim ortamları için bu kesinlikle True olmalı
    deletion_protection=True # Üretim ortamları için bu da True olmalı
)

Bu tek bir parametre değişikliği, veritabanınızın dayanıklılığını ve erişilebilirliğini önemli ölçüde artırır. Büyük bir medya şirketinin içerik yönetim sistemi, bu Multi-AZ yapısı sayesinde, bir AZ'deki elektrik kesintisine rağmen hiçbir kesinti yaşamadan çalışmaya devam etmiştir.

Veritabanı Kimlik Bilgileri Yönetimi: AWS Secrets Manager ile Entegrasyon

Veritabanı şifrelerini kod içinde veya yapılandırma dosyalarında düz metin olarak saklamak büyük bir güvenlik riskidir. AWS Secrets Manager, bu tür hassas bilgileri güvenli bir şekilde depolamanızı ve yönetmenizi sağlar. CDK ile RDS örneği oluştururken, kimlik bilgilerini doğrudan Secrets Manager'dan alacak şekilde yapılandırabiliriz. Daha önce gösterdiğimiz kodda bu entegrasyonu zaten yapmıştık:


db_credentials_secret = secretsmanager.Secret(self, "DBCredentialsSecret",
    secret_name="PostgresDbCredentials",
    generate_secret_string=secretsmanager.SecretStringGenerator(
        secret_string_template='{"username": "postgres"}',
        exclude_characters='@/"\'\\',
        password_length=16
    )
)

self.db_instance = rds.DatabaseInstance(self, "PostgresInstance",
    # ...
    credentials=rds.Credentials.from_secret(db_credentials_secret),
    # ...
)

Bu, uygulamanızın veritabanına bağlanmak için Secrets Manager'dan dinamik olarak kimlik bilgilerini çekmesini sağlar. Geliştiricilerin veya CI/CD boru hatlarının hassas bilgilere doğrudan erişmesini engeller. Bu durum, finans sektöründeki bir şirket için uyumluluk gereksinimlerini karşılamada kritik bir rol oynamıştır.

CI/CD Entegrasyonu: Otomatik Dağıtımlar Nasıl Yapılır?

AWS CDK kodunuzu bir CI/CD boru hattına entegre etmek, altyapı değişikliklerinin otomatik olarak test edilmesini ve dağıtılmasını sağlar. Bu, insan hatasını azaltır, dağıtım hızını artırır ve tutarlılığı garanti eder. AWS CodePipeline, GitHub Actions veya GitLab CI gibi araçları kullanarak CDK uygulamalarınızı otomatikleştirebilirsiniz.

Örnek bir GitHub Actions iş akışı (workflow) şöyle görünebilir:


# .github/workflows/deploy-cdk.yml
name: CDK Deploy

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.9'

    - name: Install Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '16'

    - name: Install dependencies
      run: |
        npm install -g aws-cdk
        python -m venv .venv
        source .venv/bin/activate
        pip install -r requirements.txt
        pip install aws-cdk.aws-ec2 aws-cdk.aws-rds aws-cdk.aws-secretsmanager

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v2
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: us-east-1 # Kendi bölgenizi buraya yazın

    - name: CDK Bootstrap
      run: cdk bootstrap aws://${{ secrets.AWS_ACCOUNT_ID }}/us-east-1

    - name: CDK Synth
      run: cdk synth

    - name: CDK Deploy
      run: cdk deploy --require-approval never # Üretim ortamlarında --require-approval 'never' kullanmaktan kaçının

Bu iş akışı, her main branch'ine yapılan push veya pull request'te CDK kodunuzu sentezler ve dağıtır. Bu, bir SaaS şirketinin yeni özelliklerini veya altyapı güncellemelerini haftalar yerine saatler içinde yayınlamasını sağlayarak pazara sunma süresini (Time-to-Market) önemli ölçüde kısaltmıştır.

Sonuç ve Gelecek Adımlar

Bu kapsamlı rehberde, AWS CDK ve Python'ın gücünü kullanarak güvenli ve otomatik bir PostgreSQL veritabanı altyapısını nasıl oluşturacağımızı detaylı bir şekilde inceledik. Bir Virtual Private Cloud (VPC) içinde izole edilmiş, bir Bastion host üzerinden güvenli erişim sağlayan ve AWS RDS ile yönetilen bir PostgreSQL örneğini adım adım dağıttık. Ayrıca, maliyet optimizasyonu, felaket kurtarma, kimlik bilgileri yönetimi ve CI/CD entegrasyonu gibi gerçek dünya senaryolarını ele alarak, CDK'nın sadece dağıtım aracı olmanın ötesinde, tüm yaşam döngüsü boyunca altyapıyı yönetmede ne kadar değerli bir araç olduğunu gösterdik. Bu yaklaşımlar, modern bulut mimarilerinde verimlilik, güvenlik ve ölçeklenebilirlik sağlamanın temelini oluşturur.

AWS CDK ile altyapıyı kod olarak yönetmek, geliştirme ekiplerine daha fazla kontrol, tutarlılık ve otomasyon yeteneği sunar. Python gibi tanıdık bir programlama diliyle çalışmak, öğrenme eğrisini azaltır ve daha karmaşık, mantıksal altyapı tanımlamalarına olanak tanır. Artık manuel yapılandırmaların getirdiği hatalardan, güvenlik risklerinden ve zaman kayıplarından kurtulabilir, bunun yerine iş değerine odaklanabilirsiniz. Bu rehberin sunduğu bilgilerle, kendi AWS altyapınızı daha bilinçli ve güvenli bir şekilde tasarlayabilecek ve yönetebileceksiniz.

Gelecek adımlar olarak, CDK bilginizi daha da ileriye taşımak için AWS servislerinin daha karmaşık entegrasyonlarını (örneğin, Fargate, Lambda, SQS, SNS) keşfedebilir, kendi özel CDK yapılarını (constructs) oluşturabilir ve çoklu hesap/çoklu bölge dağıtımlarını otomatize etme üzerine yoğunlaşabilirsiniz. Unutmayın, bulut altyapısı sürekli gelişen bir alandır ve sürekli öğrenme, başarının anahtarıdır.

Sıkça Sorulan Sorular (SSS)

1. AWS CDK nedir ve neden kullanmalıyım?

AWS Cloud Development Kit (CDK), AWS kaynaklarını tanıdık programlama dilleri (Python, TypeScript, Java vb.) kullanarak tanımlamanıza olanak tanıyan bir açık kaynaklı yazılım geliştirme çerçevesidir. Geleneksel JSON/YAML tabanlı CloudFormation şablonlarına göre daha üst düzey bir soyutlama sunar. CDK kullanmak, altyapıyı kod olarak (IaC) yönetmenizi, tekrarlanabilir, sürdürülebilir ve ölçeklenebilir altyapılar oluşturmanızı sağlar. Daha hızlı dağıtım, daha az hata ve daha iyi sürüm kontrolü gibi avantajlar sunar.

2. Bastion Host kullanmak zorunlu mu?

Hayır, zorunlu değildir, ancak yüksek güvenlik gerektiren ortamlarda şiddetle tavsiye edilir. Bastion host, özel alt ağlarda bulunan kaynaklara (veritabanları, uygulama sunucuları) güvenli ve denetlenebilir bir erişim noktası sağlar. Direkt erişim yerine tek bir kontrollü giriş noktası oluşturarak saldırı yüzeyini azaltır. Alternatif olarak AWS Systems Manager Session Manager gibi servicesiz çözümler de kullanılabilir, ancak Bastion host hala birçok senaryoda basit ve etkili bir çözümdür.

3. AWS RDS'in avantajları nelerdir?

AWS RDS, ilişkisel veritabanı yönetimiyle ilgili birçok operasyonel görevi (yedekleme, yama uygulama, yazılım yükseltmeleri, donanım tedariki, arıza tespiti ve kurtarma) AWS'nin üstlenmesini sağlayarak önemli avantajlar sunar. Yüksek erişilebilirlik (Multi-AZ), otomatik yedeklemeler, kolay ölçeklenebilirlik, güvenlik grupları ile entegrasyon ve çeşitli veritabanı motoru seçenekleri (PostgreSQL, MySQL, SQL Server vb.) ile geliştiricilerin veritabanı altyapısıyla uğraşmak yerine uygulama geliştirmeye odaklanmasını sağlar.

4. CDK kodunu nasıl versiyonlarım ve CI/CD ile nasıl entegre ederim?

CDK kodu, normal bir yazılım projesi gibi sürüm kontrol sistemleri (Git, GitHub, GitLab, Bitbucket vb.) ile versiyonlanmalıdır. requirements.txt dosyanızı ve CDK kodunuzu repository'nize ekleyerek değişiklikleri takip edebilirsiniz. CI/CD entegrasyonu için, GitHub Actions, AWS CodePipeline veya Jenkins gibi araçları kullanabilirsiniz. Bu araçlar, kodunuzda yapılan her değişikliği otomatik olarak test edebilir, sentezleyebilir (cdk synth) ve AWS hesabınıza dağıtabilir (cdk deploy), böylece sürekli bir dağıtım süreci oluşturabilirsiniz.

5. Dağıtılan AWS kaynaklarının maliyetlerini nasıl izleyebilirim?

AWS kaynaklarının maliyetlerini izlemek için AWS Cost Explorer ve AWS Budgets gibi yerleşik araçları kullanabilirsiniz. Ayrıca, CDK'da kaynaklarınızı etiketleyerek (tagging) maliyetleri daha granüler bir şekilde takip edebilirsiniz. Örneğin, her CDK Stack'inize bir Environment (Geliştirme, Test, Üretim) veya Project etiketi ekleyerek, maliyet raporlarında bu etiketlere göre filtreleme yapabilir ve hangi ortamın veya projenin ne kadar harcadığını net bir şekilde görebilirsiniz. Bu, maliyet optimizasyonu ve bütçeleme için kritik öneme sahiptir.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Exit mobile version