{"id":32802,"date":"2025-10-26T04:31:36","date_gmt":"2025-10-26T01:31:36","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/"},"modified":"2025-10-26T04:31:36","modified_gmt":"2025-10-26T01:31:36","slug":"terraform-s3-ve-github-actions-ile-altyapi-otomasyonu","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/","title":{"rendered":"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu"},"content":{"rendered":"<p><body><\/p>\n<style>\n    \/* Genel stiller *\/\n    body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; margin: 0; padding: 20px; }\n    h2, h3 { color: #2c3e50; margin-top: 30px; margin-bottom: 15px; }\n    p { margin-bottom: 15px; }\n    pre { background-color: #f4f4f4; padding: 15px; border-radius: 5px; overflow-x: auto; margin-bottom: 20px; }\n    code { font-family: 'Courier New', monospace; background-color: #e9e9e9; padding: 2px 4px; border-radius: 3px; }\n    .tip { background-color: #e8f5e9; border-left: 5px solid #4CAF50; padding: 15px; margin-bottom: 20px; color: #388e3c; }\n    ul { list-style-type: disc; margin-left: 20px; margin-bottom: 15px; }\n    ol { list-style-type: decimal; margin-left: 20px; margin-bottom: 15px; }\n    table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }\n    th, td { border: 1px solid #ddd; padding: 10px; text-align: left; }\n    th { background-color: #f2f2f2; font-weight: bold; }<\/p>\n<p>    \/* Masa\u00fcst\u00fc i\u00e7in varsay\u0131lan stil *\/\n    .container {\n      max-width: 960px;\n      margin: 0 auto;\n      padding: 20px;\n    }<\/p>\n<p>    \/* Mobil cihazlar i\u00e7in medya sorgusu *\/\n    @media (max-width: 768px) {\n      body {\n        padding: 10px;\n      }\n      .container {\n        padding: 0;\n      }\n      h2 {\n        font-size: 1.6em;\n      }\n      h3 {\n        font-size: 1.3em;\n      }\n      pre {\n        white-space: pre-wrap; \/* Uzun kod sat\u0131rlar\u0131n\u0131 sarar *\/\n        word-wrap: break-word;\n      }\n      table, thead, tbody, th, td, tr {\n        display: block; \/* Tablo elemanlar\u0131n\u0131 blok olarak g\u00f6sterir *\/\n      }\n      thead tr {\n        position: absolute;\n        top: -9999px;\n        left: -9999px;\n      }\n      tr { border: 1px solid #ccc; margin-bottom: 10px; }\n      td {\n        border: none;\n        border-bottom: 1px solid #eee;\n        position: relative;\n        padding-left: 50%;\n        text-align: right;\n      }\n      td:before {\n        position: absolute;\n        top: 6px;\n        left: 6px;\n        width: 45%;\n        padding-right: 10px;\n        white-space: nowrap;\n        text-align: left;\n        font-weight: bold;\n        content: attr(data-label); \/* data-label niteli\u011fini kullan *\/\n      }\n      \/* Her bir s\u00fctun ba\u015fl\u0131\u011f\u0131 i\u00e7in content \u00f6zelli\u011fi tan\u0131mlay\u0131n (\u00f6rnek) *\/\n      \/* Daha iyi bir \u00e7\u00f6z\u00fcm i\u00e7in JS ile dinamik olarak data-label eklemek tercih edilebilir *\/\n    }\n  <\/style>\n<div class=\"container\">\n<p>Modern yaz\u0131l\u0131m d\u00fcnyas\u0131nda altyap\u0131 y\u00f6netimi zorlay\u0131c\u0131 ve zaman al\u0131c\u0131 bir s\u00fcre\u00e7 olabilir. Bu makale, Terraform, AWS S3 ve GitHub Actions&#8217;\u0131 kullanarak altyap\u0131n\u0131z\u0131 nas\u0131l otomatikle\u015ftirece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131klayacakt\u0131r.<\/p>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn h\u0131zla de\u011fi\u015fen teknoloji d\u00fcnyas\u0131nda, yaz\u0131l\u0131m geli\u015ftirme s\u00fcre\u00e7leri s\u00fcrekli olarak evrim ge\u00e7iriyor. Manuel altyap\u0131 y\u00f6netimi, bir zamanlar standart bir uygulama olsa da, beraberinde bir\u00e7ok zorlu\u011fu getiriyor: insan hatas\u0131 riski, uzun da\u011f\u0131t\u0131m s\u00fcreleri, ortamlar aras\u0131 tutars\u0131zl\u0131klar ve en \u00f6nemlisi \u00f6l\u00e7eklenebilirlik sorunlar\u0131. \u00d6rne\u011fin, yeni bir \u00f6zelli\u011fi devreye almak i\u00e7in onlarca sunucuyu tek tek yap\u0131land\u0131rmak, hem yorucu hem de hata pay\u0131 y\u00fcksek bir i\u015flemdir. Bu durum, \u00f6zellikle h\u0131zla b\u00fcy\u00fcyen startup&#8217;lar ve b\u00fcy\u00fck \u00f6l\u00e7ekli kurumsal \u015firketler i\u00e7in ciddi bir darbo\u011faz olu\u015fturur. Bir startup&#8217;\u0131n \u00fcr\u00fcn\u00fcn\u00fc piyasaya s\u00fcrmesi veya mevcut bir e-ticaret platformunun Kara Cuma gibi yo\u011fun d\u00f6nemlerde ani trafik art\u0131\u015flar\u0131na yan\u0131t vermesi gerekti\u011finde, manuel s\u00fcre\u00e7ler operasyonel bir kabusa d\u00f6n\u00fc\u015febilir.<\/p>\n<p>\u0130\u015fte tam bu noktada Altyap\u0131 Kod Olarak (Infrastructure as Code &#8211; IaC) kavram\u0131 devreye giriyor. IaC, sunucular, veritabanlar\u0131, a\u011f yap\u0131land\u0131rmalar\u0131 ve di\u011fer bulut kaynaklar\u0131 gibi altyap\u0131 bile\u015fenlerini kod dosyalar\u0131 arac\u0131l\u0131\u011f\u0131yla tan\u0131mlama ve y\u00f6netme prati\u011fidir. Bu yakla\u015f\u0131m, geleneksel manuel s\u00fcre\u00e7lerin aksine, altyap\u0131n\u0131n versiyon kontrol sistemlerinde (\u00f6rne\u011fin Git) saklanmas\u0131n\u0131, test edilmesini ve otomatik olarak da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flar. B\u00f6ylece altyap\u0131, yaz\u0131l\u0131m kodu gibi ele al\u0131n\u0131r ve ayn\u0131 disiplin ve s\u00fcre\u00e7lerden ge\u00e7er.<\/p>\n<p>IaC&#8217;nin benimsenmesi, geli\u015ftirme ekiplerine bir\u00e7ok \u00f6nemli avantaj sunar. Her \u015feyden \u00f6nce, da\u011f\u0131t\u0131m s\u00fcre\u00e7leri inan\u0131lmaz derecede h\u0131zlan\u0131r. Yeni bir ortam\u0131 saniyeler veya dakikalar i\u00e7inde aya\u011fa kald\u0131rmak m\u00fcmk\u00fcn hale gelir. \u0130kincisi, tutarl\u0131l\u0131k sa\u011flan\u0131r. Kod tabanl\u0131 tan\u0131mlamalar sayesinde, geli\u015ftirme, test ve \u00fcretim ortamlar\u0131 aras\u0131nda neredeyse m\u00fckemmel bir uyum elde edilir, bu da &#8220;benim makinemde \u00e7al\u0131\u015f\u0131yordu&#8221; gibi sorunlar\u0131n \u00f6n\u00fcne ge\u00e7er. \u00dc\u00e7\u00fcnc\u00fcs\u00fc, hata riski \u00f6nemli \u00f6l\u00e7\u00fcde azal\u0131r. Otomatik da\u011f\u0131t\u0131m, manuel yap\u0131land\u0131rmadan kaynaklanan yanl\u0131\u015f yaz\u0131m hatalar\u0131n\u0131 veya eksik ad\u0131mlar\u0131 ortadan kald\u0131r\u0131r. Son olarak, IaC maliyet kontrol\u00fc konusunda da \u00f6nemli faydalar sunar. Kullan\u0131lmayan veya gereksiz kaynaklar\u0131 tespit etmek ve otomatik olarak sonland\u0131rmak daha kolay hale gelir, b\u00f6ylece bulut faturan\u0131zda \u00f6nemli \u00f6l\u00e7\u00fcde tasarruf sa\u011flanabilir. DevOps k\u00fclt\u00fcr\u00fcn\u00fcn ve CI\/CD (S\u00fcrekli Entegrasyon\/S\u00fcrekli Da\u011f\u0131t\u0131m) pratiklerinin merkezinde yer alan IaC, modern bulut bili\u015fim ortamlar\u0131nda ba\u015far\u0131l\u0131 olman\u0131n vazge\u00e7ilmez bir bile\u015fenidir.<\/p>\n<h3>Terraform Nedir ve Temel Kavramlar\u0131 Nelerdir?<\/h3>\n<p>Altyap\u0131 Kod Olarak (IaC) d\u00fcnyas\u0131n\u0131n en pop\u00fcler ve g\u00fc\u00e7l\u00fc ara\u00e7lar\u0131ndan biri hi\u00e7 \u015f\u00fcphesiz HashiCorp Terraform&#8217;dur. Terraform, deklaratif bir yakla\u015f\u0131mla altyap\u0131n\u0131z\u0131 tan\u0131mlaman\u0131za, sa\u011flaman\u0131za ve y\u00f6netmenize olanak tan\u0131yan a\u00e7\u0131k kaynakl\u0131 bir ara\u00e7t\u0131r. Farkl\u0131 bulut sa\u011flay\u0131c\u0131lar\u0131 (AWS, Azure, Google Cloud) ve di\u011fer servislerle (Kubernetes, VMWare vb.) entegre olabilen evrensel yap\u0131s\u0131 sayesinde, \u00e7oklu bulut stratejileri uygulayan \u015firketler i\u00e7in vazge\u00e7ilmez bir \u00e7\u00f6z\u00fcm haline gelmi\u015ftir.<\/p>\n<p>Terraform&#8217;un temelinde birka\u00e7 ana kavram bulunur:<\/p>\n<ul>\n<li><strong>Providers (Sa\u011flay\u0131c\u0131lar):<\/strong> Terraform&#8217;un belirli bir altyap\u0131 platformu veya hizmetiyle etkile\u015fim kurmas\u0131n\u0131 sa\u011flayan eklentilerdir. \u00d6rne\u011fin, AWS kaynaklar\u0131n\u0131 y\u00f6netmek i\u00e7in <code>aws<\/code> sa\u011flay\u0131c\u0131s\u0131n\u0131, Azure kaynaklar\u0131 i\u00e7in <code>azurerm<\/code> sa\u011flay\u0131c\u0131s\u0131n\u0131 kullan\u0131r\u0131z. Bu sa\u011flay\u0131c\u0131lar, API \u00e7a\u011fr\u0131lar\u0131 yaparak kaynaklar\u0131 olu\u015fturur, g\u00fcnceller veya siler.<\/li>\n<li><strong>Resources (Kaynaklar):<\/strong> Y\u00f6netmek istedi\u011fimiz altyap\u0131 bile\u015fenleridir. Bir AWS EC2 \u00f6rne\u011fi, bir S3 kovas\u0131, bir veritaban\u0131 veya bir sanal a\u011f gibi her \u015fey bir Terraform kayna\u011f\u0131 olarak tan\u0131mlan\u0131r. Kaynaklar, istenen durumu (<code>desired state<\/code>) bildiren deklaratif kod bloklar\u0131 ile tan\u0131mlan\u0131r.<\/li>\n<li><strong>Data Sources (Veri Kaynaklar\u0131):<\/strong> Mevcut altyap\u0131daki bilgileri okumak i\u00e7in kullan\u0131l\u0131r. \u00d6rne\u011fin, mevcut bir AMI (Amazon Machine Image) ID&#8217;sini almak veya var olan bir VPC&#8217;nin (Virtual Private Cloud) ID&#8217;sini sorgulamak i\u00e7in veri kaynaklar\u0131ndan faydalan\u0131r\u0131z. Bu, Terraform&#8217;un yeni kaynaklar olu\u015ftururken mevcut kaynaklarla etkile\u015fim kurmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Modules (Mod\u00fcller):<\/strong> Terraform kodunu mant\u0131ksal olarak grupland\u0131rmak ve tekrar kullan\u0131labilir hale getirmek i\u00e7in kullan\u0131lan temel yap\u0131d\u0131r. Bir mod\u00fcl, bir veya daha fazla kaynak tan\u0131m\u0131n\u0131 kapsayan bir klas\u00f6rden ibarettir. \u00d6rne\u011fin, bir web sunucusu (EC2), g\u00fcvenlik grubu ve y\u00fck dengeleyiciyi i\u00e7eren bir mod\u00fcl olu\u015fturarak, bu yap\u0131land\u0131rmay\u0131 farkl\u0131 projelerde veya ortamlarda kolayca tekrar kullanabilirsiniz. Bu, kod tekrar\u0131n\u0131 azalt\u0131r ve b\u00fcy\u00fck altyap\u0131lar\u0131n y\u00f6netimini basitle\u015ftirir.<\/li>\n<\/ul>\n<p>Terraform&#8217;un i\u015f ak\u0131\u015f\u0131 genellikle \u015fu komutlarla ilerler:<\/p>\n<ol>\n<li><code>terraform init<\/code>: \u00c7al\u0131\u015fma dizinini ba\u015flat\u0131r, sa\u011flay\u0131c\u0131 eklentilerini indirir ve backend yap\u0131land\u0131rmas\u0131n\u0131 kurar.<\/li>\n<li><code>terraform plan<\/code>: Kodunuzun mevcut altyap\u0131yla kar\u015f\u0131la\u015ft\u0131r\u0131ld\u0131\u011f\u0131nda ne gibi de\u011fi\u015fiklikler yapaca\u011f\u0131n\u0131 g\u00f6steren bir y\u00fcr\u00fctme plan\u0131 olu\u015fturur. Bu ad\u0131m, da\u011f\u0131t\u0131m \u00f6ncesi olas\u0131 hatalar\u0131 ve istenmeyen de\u011fi\u015fiklikleri tespit etmek i\u00e7in kritik \u00f6neme sahiptir.<\/li>\n<li><code>terraform apply<\/code>: <code>plan<\/code> taraf\u0131ndan belirlenen de\u011fi\u015fiklikleri ger\u00e7ek altyap\u0131da uygular. Bu komut genellikle bir onay gerektirir, ancak otomasyon senaryolar\u0131nda <code>-auto-approve<\/code> bayra\u011f\u0131 ile bu onay ad\u0131m\u0131 atlanabilir.<\/li>\n<li><code>terraform destroy<\/code>: Terraform taraf\u0131ndan y\u00f6netilen t\u00fcm kaynaklar\u0131 kald\u0131r\u0131r. Dikkatli kullan\u0131lmas\u0131 gereken, geri d\u00f6n\u00fc\u015f\u00fc olmayan bir i\u015flemdir.<\/li>\n<\/ol>\n<p>Terraform&#8217;un en kritik bile\u015fenlerinden biri ise <strong>state dosyas\u0131d\u0131r<\/strong> (genellikle <code>terraform.tfstate<\/code>). Bu dosya, Terraform&#8217;un y\u00f6netti\u011fi ger\u00e7ek altyap\u0131 kaynaklar\u0131 ile kodunuzda tan\u0131mlad\u0131\u011f\u0131n\u0131z istenen durum aras\u0131ndaki e\u015fle\u015fmeyi sa\u011flar. Yani, Terraform&#8217;un &#8220;nerede oldu\u011funu&#8221; ve &#8220;ne yapt\u0131\u011f\u0131n\u0131&#8221; kaydetti\u011fi bir referans noktas\u0131d\u0131r. State dosyas\u0131, kaynaklar\u0131n ID&#8217;leri, \u00f6znitelikleri ve ba\u011f\u0131ml\u0131l\u0131klar\u0131 gibi hassas bilgileri i\u00e7erebilir. Bu nedenle, state dosyas\u0131n\u0131n g\u00fcvenli, versiyonlanabilir ve merkezi bir yerde saklanmas\u0131, \u00f6zellikle ekip ortamlar\u0131nda \u00e7al\u0131\u015f\u0131rken hayati \u00f6nem ta\u015f\u0131r. \u0130\u015fte bu y\u00fczden uzaktan state y\u00f6netimi, \u00f6zellikle AWS S3 gibi \u00e7\u00f6z\u00fcmlerle, vazge\u00e7ilmez bir uygulama haline gelmi\u015ftir.<\/p>\n<p>Basit bir AWS EC2 \u00f6rne\u011fi ile Terraform kod yap\u0131s\u0131na g\u00f6z atal\u0131m:<\/p>\n<pre><code>\nresource \"aws_instance\" \"web_server\" {\n  ami           = \"ami-0abcdef1234567890\" # L\u00fctfen g\u00fcncel ve b\u00f6lgenize uygun bir AMI ID kullan\u0131n\n  instance_type = \"t2.micro\"\n  tags = {\n    Name = \"MyWebServer\"\n    Environment = \"Dev\"\n  }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu kod blo\u011fu, AWS \u00fczerinde tek bir EC2 \u00f6rne\u011fi olu\u015fturmak i\u00e7in yeterlidir. Ancak ger\u00e7ek d\u00fcnya senaryolar\u0131nda, bu kod \u00e7ok daha karma\u015f\u0131k hale gelebilir ve birden fazla kaynaktan olu\u015fur.<\/p>\n<h2>Neden Uzaktan Terraform Durumu (State) Y\u00f6netmeliyiz: AWS S3 Backend'in G\u00fcc\u00fc<\/h2>\n<p>Terraform'un state dosyas\u0131 (<code>.tfstate<\/code>), y\u00f6netti\u011fi altyap\u0131n\u0131n mevcut durumunu i\u00e7eren kritik bir JSON dosyas\u0131d\u0131r. Ba\u015flang\u0131\u00e7ta, Terraform bu dosyay\u0131 yerel \u00e7al\u0131\u015fma dizininizde olu\u015fturur. Ancak, bu yerel yakla\u015f\u0131m, bireysel projeler veya tek ki\u015filik ekipler i\u00e7in uygun olsa da, daha b\u00fcy\u00fck ekipler veya \u00fcretim ortamlar\u0131 i\u00e7in ciddi s\u0131n\u0131rlamalara ve risklere sahiptir. Yerel state dosyas\u0131n\u0131n dezavantajlar\u0131 \u015funlard\u0131r:<\/p>\n<ul>\n<li><strong>Tak\u0131m \u00c7al\u0131\u015fmas\u0131 Zorlu\u011fu:<\/strong> Birden fazla geli\u015ftirici ayn\u0131 altyap\u0131 \u00fczerinde \u00e7al\u0131\u015ft\u0131\u011f\u0131nda, yerel state dosyalar\u0131 kolayca \u00e7ak\u0131\u015fabilir ve tutars\u0131zl\u0131klara yol a\u00e7abilir. Bir geli\u015ftirici de\u011fi\u015fiklik yap\u0131p state dosyas\u0131n\u0131 g\u00fcncelledi\u011finde, di\u011ferlerinin bu g\u00fcncellemeyi manuel olarak almas\u0131 gerekir, bu da hata e\u011filimini art\u0131r\u0131r.<\/li>\n<li><strong>Versiyon Kontrol\u00fc Eksikli\u011fi:<\/strong> Yerel state dosyas\u0131, genellikle Git gibi versiyon kontrol sistemlerine do\u011frudan dahil edilmez (g\u00fcvenlik ve boyut nedeniyle). Bu durum, altyap\u0131n\u0131n belirli bir zamandaki durumunu takip etmeyi veya \u00f6nceki bir duruma geri d\u00f6nmeyi zorla\u015ft\u0131r\u0131r.<\/li>\n<li><strong>G\u00fcvenlik Riski:<\/strong> State dosyas\u0131, IP adresleri, DNS kay\u0131tlar\u0131 ve hatta hassas API anahtarlar\u0131 veya veritaban\u0131 \u015fifreleri gibi bilgileri \u015fifrelenmemi\u015f olarak i\u00e7erebilir. Yerel makinede saklanmas\u0131, yetkisiz eri\u015fim durumunda ciddi bir g\u00fcvenlik a\u00e7\u0131\u011f\u0131 olu\u015fturur.<\/li>\n<li><strong>Kay\u0131p Riski:<\/strong> Yerel makinenin \u00e7\u00f6kmesi veya dosyan\u0131n yanl\u0131\u015fl\u0131kla silinmesi, Terraform'un altyap\u0131n\u0131zla olan ba\u011flant\u0131s\u0131n\u0131 kaybetmesine ve altyap\u0131n\u0131z\u0131 y\u00f6netememesine neden olabilir. Bu durum, felaketle sonu\u00e7lanabilir ve altyap\u0131y\u0131 yeniden olu\u015fturma veya manuel olarak senkronize etme gibi zahmetli s\u00fcre\u00e7ler gerektirebilir.<\/li>\n<\/ul>\n<p>Bu sorunlar\u0131 a\u015fmak i\u00e7in Terraform, \"remote backend\" (uzaktan durum arka ucu) kavram\u0131n\u0131 sunar. Uzaktan state y\u00f6netimi, state dosyas\u0131n\u0131 merkezi ve g\u00fcvenli bir depolama konumuna ta\u015f\u0131r. AWS S3 (Simple Storage Service) bu ama\u00e7 i\u00e7in en yayg\u0131n ve \u00f6nerilen \u00e7\u00f6z\u00fcmlerden biridir. AWS S3 backend'i kullanman\u0131n faydalar\u0131 ise saymakla bitmez:<\/p>\n<ul>\n<li><strong>Tak\u0131m \u0130\u015fbirli\u011fi:<\/strong> T\u00fcm ekip \u00fcyeleri, merkezi bir state dosyas\u0131na eri\u015febilir ve altyap\u0131 de\u011fi\u015fikliklerini g\u00fcvenli bir \u015fekilde koordine edebilir.<\/li>\n<li><strong>Kilitleme Mekanizmas\u0131:<\/strong> Terraform, S3 ile birlikte AWS DynamoDB'yi kullanarak state kilitleme (state locking) mekanizmas\u0131 sa\u011flar. Bu, birden fazla kullan\u0131c\u0131n\u0131n ayn\u0131 anda <code>terraform apply<\/code> \u00e7al\u0131\u015ft\u0131rmas\u0131n\u0131 engeller ve state dosyas\u0131n\u0131n bozulmas\u0131n\u0131 \u00f6nler.<\/li>\n<li><strong>Versiyonlama:<\/strong> S3 kovalar\u0131nda versiyonlama etkinle\u015ftirildi\u011finde, state dosyas\u0131n\u0131n her s\u00fcr\u00fcm\u00fc otomatik olarak saklan\u0131r. Bu sayede, yanl\u0131\u015fl\u0131kla yap\u0131lan bir de\u011fi\u015fiklik durumunda kolayca \u00f6nceki bir s\u00fcr\u00fcme geri d\u00f6n\u00fclebilir (rollback).<\/li>\n<li><strong>\u015eifreleme:<\/strong> S3, dosyalar\u0131 depolarken AES-256 sunucu taraf\u0131 \u015fifrelemesi (SSE-S3) veya AWS Key Management Service (KMS) ile \u015fifreleme se\u00e7enekleri sunar. Bu, state dosyas\u0131ndaki hassas verilerin g\u00fcvende olmas\u0131n\u0131 sa\u011flar.<\/li>\n<li><strong>Merkezi Y\u00f6netim ve Denetim:<\/strong> State dosyas\u0131n\u0131n merkezi bir konumda olmas\u0131, g\u00fcvenlik politikalar\u0131n\u0131n uygulanmas\u0131n\u0131 ve eri\u015fim kontrollerinin y\u00f6netilmesini kolayla\u015ft\u0131r\u0131r.<\/li>\n<\/ul>\n<p>Peki, AWS S3 backend nas\u0131l yap\u0131land\u0131r\u0131l\u0131r? \u0130lk olarak, Terraform state dosyan\u0131z\u0131 saklamak i\u00e7in bir S3 kovas\u0131na ve state kilitleme i\u00e7in bir DynamoDB tablosuna ihtiyac\u0131n\u0131z vard\u0131r. Bu kaynaklar\u0131 da asl\u0131nda Terraform ile olu\u015fturabiliriz, t\u0131pk\u0131 a\u015fa\u011f\u0131daki \u00f6rnekte oldu\u011fu gibi:<\/p>\n<pre><code>\nresource \"aws_s3_bucket\" \"terraform_state\" {\n  bucket = \"my-unique-terraform-state-bucket-12345\" # Benzersiz bir isim se\u00e7melisiniz\n  acl    = \"private\"\n\n  versioning {\n    enabled = true # State dosyas\u0131n\u0131n versiyonlanmas\u0131n\u0131 sa\u011flar\n  }\n\n  server_side_encryption_configuration {\n    rule {\n      apply_server_side_encryption_by_default {\n        sse_algorithm = \"AES256\" # Varsay\u0131lan \u015fifreleme\n      }\n    }\n  }\n\n  tags = {\n    Name        = \"Terraform State Bucket\"\n    Environment = \"Dev\"\n  }\n}\n\nresource \"aws_dynamodb_table\" \"terraform_state_lock\" {\n  name           = \"terraform-state-lock-table\" # Kilitleme i\u00e7in DynamoDB tablosu\n  billing_mode   = \"PAY_PER_REQUEST\"\n  hash_key       = \"LockID\"\n\n  attribute {\n    name = \"LockID\"\n    type = \"S\"\n  }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu kaynaklar olu\u015fturulduktan sonra, Terraform yap\u0131land\u0131rma dosyan\u0131zda (genellikle <code>main.tf<\/code> veya ayr\u0131 bir <code>backend.tf<\/code> dosyas\u0131nda) S3 backend'ini tan\u0131mlayabilirsiniz:<\/p>\n<pre><code>\nterraform {\n  backend \"s3\" {\n    bucket         = \"my-unique-terraform-state-bucket-12345\"\n    key            = \"dev\/infrastructure.tfstate\" # State dosyas\u0131n\u0131n S3 i\u00e7indeki yolu\n    region         = \"us-east-1\"\n    encrypt        = true # S3 \u00fczerinde \u015fifrelenmi\u015f depolama\n    dynamodb_table = \"terraform-state-lock-table\" # Kilitleme i\u00e7in DynamoDB tablosu\n  }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu yap\u0131land\u0131rmay\u0131 ekledikten sonra, ilk <code>terraform init<\/code> komutunu \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131n\u0131zda, Terraform state dosyan\u0131z\u0131 belirtilen S3 kovas\u0131na otomatik olarak ta\u015f\u0131yacak ve DynamoDB tablosunu kilitleme mekanizmas\u0131 i\u00e7in kullanacakt\u0131r. Bu sayede, altyap\u0131 y\u00f6netiminiz daha g\u00fcvenli, i\u015fbirlik\u00e7i ve esnek hale gelir.<\/p>\n<h2>GitHub Actions ile Otomatik Altyap\u0131 Da\u011f\u0131t\u0131m\u0131 Nas\u0131l Yap\u0131l\u0131r?<\/h2>\n<p>Altyap\u0131m\u0131z\u0131 kod olarak tan\u0131mlad\u0131k ve state dosyam\u0131z\u0131 g\u00fcvenli bir \u015fekilde y\u00f6netmeyi \u00f6\u011frendik. \u015eimdi s\u0131ra geldi bu altyap\u0131y\u0131 otomatik olarak da\u011f\u0131tmaya. S\u00fcrekli Entegrasyon (CI) ve S\u00fcrekli Da\u011f\u0131t\u0131m (CD) prensipleri, yaz\u0131l\u0131m geli\u015ftirmenin ayr\u0131lmaz bir par\u00e7as\u0131 haline gelmi\u015ftir ve bu prensipler altyap\u0131 y\u00f6netimine de uygulanabilir. CI\/CD s\u00fcre\u00e7leri, kod de\u011fi\u015fikliklerinin otomatik olarak test edilmesini, derlenmesini ve da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flayarak geli\u015ftirme d\u00f6ng\u00fcs\u00fcn\u00fc h\u0131zland\u0131r\u0131r ve hatalar\u0131 azalt\u0131r.<\/p>\n<p>GitHub Actions, GitHub deposu i\u00e7inde do\u011frudan CI\/CD i\u015f ak\u0131\u015flar\u0131 olu\u015fturman\u0131za ve otomasyonu tetiklemenize olanak tan\u0131yan g\u00fc\u00e7l\u00fc bir ara\u00e7t\u0131r. Bir kod de\u011fi\u015fikli\u011fi (\u00f6rne\u011fin bir <code>push<\/code> veya <code>pull request<\/code>) gibi belirli olaylar taraf\u0131ndan tetiklenebilen \u00f6zelle\u015ftirilebilir i\u015f ak\u0131\u015flar\u0131 (workflows) tan\u0131mlayabilirsiniz. GitHub Actions, bu otomasyonu YAML dosyalar\u0131 arac\u0131l\u0131\u011f\u0131yla y\u00f6netir, bu da i\u015f ak\u0131\u015flar\u0131n\u0131z\u0131n da kod olarak versiyonlanabilmesi anlam\u0131na gelir.<\/p>\n<p>Bir GitHub Actions i\u015f ak\u0131\u015f\u0131 (workflow) temel olarak \u015fu bile\u015fenlerden olu\u015fur:<\/p>\n<ul>\n<li><code>on<\/code>: \u0130\u015f ak\u0131\u015f\u0131n\u0131 tetikleyecek olaylar\u0131 tan\u0131mlar (\u00f6rne\u011fin, <code>push<\/code>, <code>pull_request<\/code>, <code>schedule<\/code>).<\/li>\n<li><code>jobs<\/code>: \u0130\u015f ak\u0131\u015f\u0131n\u0131n i\u00e7inde \u00e7al\u0131\u015facak bir veya daha fazla i\u015fi tan\u0131mlar. Her i\u015f, birbirinden ba\u011f\u0131ms\u0131z olarak veya ba\u011f\u0131ml\u0131l\u0131klar tan\u0131mlanarak \u00e7al\u0131\u015fabilir.<\/li>\n<li><code>steps<\/code>: Her bir i\u015fin i\u00e7inde y\u00fcr\u00fct\u00fclecek komutlar\u0131 veya eylemleri (actions) tan\u0131mlar. Bir ad\u0131m, bir komut \u00e7al\u0131\u015ft\u0131rmak veya bir GitHub Action'\u0131 kullanmak olabilir.<\/li>\n<\/ul>\n<p>Terraform ile altyap\u0131 da\u011f\u0131t\u0131m\u0131n\u0131 otomatikle\u015ftirmek i\u00e7in GitHub Actions'\u0131 nas\u0131l kullanaca\u011f\u0131m\u0131za ad\u0131m ad\u0131m bakal\u0131m:<\/p>\n<ol>\n<li><strong>GitHub Repository Olu\u015fturma:<\/strong> Terraform kodunuzu i\u00e7eren bir GitHub deposu olu\u015fturun veya mevcut bir depoyu kullan\u0131n.<\/li>\n<li><strong>AWS Kimlik Bilgileri ve GitHub Secrets:<\/strong> GitHub Actions'\u0131n AWS kaynaklar\u0131n\u0131za eri\u015febilmesi i\u00e7in kimlik bilgilerine ihtiyac\u0131 vard\u0131r. AWS'te bir IAM kullan\u0131c\u0131s\u0131 olu\u015fturun, bu kullan\u0131c\u0131ya Terraform'un olu\u015fturaca\u011f\u0131 kaynaklar\u0131 y\u00f6netme yetkisi veren bir politika (least privilege prensibiyle) atay\u0131n ve bu kullan\u0131c\u0131n\u0131n Eri\u015fim Anahtar\u0131 Kimli\u011fi (Access Key ID) ile Gizli Eri\u015fim Anahtar\u0131n\u0131 (Secret Access Key) al\u0131n. Bu anahtarlar\u0131 do\u011frudan YAML dosyan\u0131za yazmak yerine, GitHub Secrets olarak depolaman\u0131z hayati derecede \u00f6nemlidir. Deponuzda \"Settings -> Secrets -> Actions\" b\u00f6l\u00fcm\u00fcne giderek <code>AWS_ACCESS_KEY_ID<\/code> ve <code>AWS_SECRET_ACCESS_KEY<\/code> ad\u0131nda iki yeni s\u0131r olu\u015fturun.<\/li>\n<li><strong>Workflow YAML Dosyas\u0131n\u0131 Olu\u015fturma:<\/strong> Deponuzun k\u00f6k dizininde <code>.github\/workflows\/<\/code> ad\u0131nda bir klas\u00f6r olu\u015fturun ve i\u00e7ine <code>main.yml<\/code> (veya istedi\u011finiz ba\u015fka bir isimde) bir YAML dosyas\u0131 ekleyin. Bu dosya, CI\/CD i\u015f ak\u0131\u015f\u0131n\u0131z\u0131 i\u00e7erecektir.<\/li>\n<\/ol>\n<p>A\u015fa\u011f\u0131da, bir <code>push<\/code> olay\u0131 (\u00f6zellikle <code>main<\/code> branch'e) veya bir <code>pull_request<\/code> a\u00e7\u0131ld\u0131\u011f\u0131nda Terraform plan\u0131 olu\u015fturup, <code>main<\/code> branch'e yap\u0131lan birle\u015ftirme (merge) sonras\u0131 Terraform'u uygulayan \u00f6rnek bir GitHub Actions workflow YAML dosyas\u0131 bulunmaktad\u0131r:<\/p>\n<pre><code>\nname: Terraform AWS Altyap\u0131s\u0131 Da\u011f\u0131t\u0131m\u0131\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    branches:\n      - main\n\njobs:\n  terraform:\n    name: 'Terraform Plan ve Uygulama'\n    runs-on: ubuntu-latest # \u0130\u015fin \u00e7al\u0131\u015faca\u011f\u0131 i\u015fletim sistemi\n\n    steps:\n      - name: 'Depoyu Kontrol Et'\n        uses: actions\/checkout@v3 # Depoyu GitHub Actions ortam\u0131na kopyalar\n\n      - name: 'Terraform CLI Kur'\n        uses: hashicorp\/setup-terraform@v2 # Terraform CLI'\u0131 kurar\n        with:\n          terraform_version: 1.5.0 # \u0130stedi\u011finiz Terraform s\u00fcr\u00fcm\u00fc\n\n      - name: 'AWS Kimlik Bilgilerini Yap\u0131land\u0131r'\n        uses: aws-actions\/configure-aws-credentials@v2 # AWS kimlik bilgilerini ayarlar\n        with:\n          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}\n          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}\n          aws-region: us-east-1 # Kullanaca\u011f\u0131n\u0131z AWS b\u00f6lgesi\n\n      - name: 'Terraform Ba\u015flat'\n        id: init\n        run: terraform init # Terraform backend'ini ba\u015flat\u0131r\n\n      - name: 'Terraform Plan Olu\u015ftur'\n        id: plan\n        run: terraform plan -no-color -input=false -out=tfplan.out\n        # -no-color: \u00e7\u0131kt\u0131n\u0131n renkli olmamas\u0131n\u0131 sa\u011flar\n        # -input=false: interaktif giri\u015fleri kapat\u0131r\n        # -out=tfplan.out: plan \u00e7\u0131kt\u0131s\u0131n\u0131 bir dosyaya kaydeder\n\n      - name: 'Terraform Plan\u0131 Yorumlarda G\u00f6ster'\n        if: github.event_name == 'pull_request' # Sadece pull requestler i\u00e7in \u00e7al\u0131\u015f\u0131r\n        uses: actions\/github-script@v6\n        with:\n          script: |\n            const output = <code><strong>## Terraform Plan <\/strong>\n            \\<\/code>\\<code>\\<\/code>\n            ${process.env.TF_PLAN_OUTPUT}\n            \\<code>\\<\/code>\\<code><\/code>;\n            github.rest.issues.createComment({\n              issue_number: context.issue.number,\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              body: output\n            })\n          env:\n            TF_PLAN_OUTPUT: ${{ steps.plan.outputs.stdout }} # Plan \u00e7\u0131kt\u0131s\u0131n\u0131 yorum olarak ekler\n\n      - name: 'Terraform Uygula'\n        # Sadece main branch'e yap\u0131lan push'larda otomatik olarak uygular\n        if: github.ref == 'refs\/heads\/main' && github.event_name == 'push' \n        run: terraform apply -auto-approve tfplan.out\n    <\/pre>\n<p><\/code><\/p>\n<div class=\"tip\">\n      Uzman \u0130pucu: Otomatik <code>apply<\/code> ad\u0131m\u0131 yerine, <code>pull_request<\/code> a\u00e7\u0131ld\u0131\u011f\u0131nda <code>plan<\/code> yap\u0131p, <code>main<\/code> branch'e birle\u015ftirildi\u011finde manuel onay sonras\u0131 veya ayr\u0131 bir i\u015f ak\u0131\u015f\u0131 ile <code>apply<\/code> yapmak, \u00fcretim ortamlar\u0131 i\u00e7in daha g\u00fcvenli bir CI\/CD stratejisidir. Bu, istenmeyen de\u011fi\u015fikliklerin \u00f6n\u00fcne ge\u00e7erek daha kontroll\u00fc bir da\u011f\u0131t\u0131m sa\u011flar.\n    <\/div>\n<p>Bu i\u015f ak\u0131\u015f\u0131, her <code>push<\/code> veya <code>pull_request<\/code> olay\u0131nda Terraform plan\u0131n\u0131 \u00e7al\u0131\u015ft\u0131racak ve <code>pull_request<\/code> durumunda plan \u00e7\u0131kt\u0131s\u0131n\u0131 do\u011frudan GitHub yorumlar\u0131na ekleyecektir. Bu sayede, ekip \u00fcyeleri birle\u015ftirme yapmadan \u00f6nce yap\u0131lacak de\u011fi\u015fiklikleri kolayca g\u00f6zden ge\u00e7irebilir. <code>main<\/code> branch'e birle\u015ftirme (merge) i\u015flemi sonras\u0131 yap\u0131lan <code>push<\/code>'larda ise, Terraform otomatik olarak <code>apply<\/code> komutunu \u00e7al\u0131\u015ft\u0131rarak altyap\u0131 de\u011fi\u015fikliklerini AWS'e uygulayacakt\u0131r. Bu sayede, altyap\u0131 da\u011f\u0131t\u0131m s\u00fcre\u00e7leriniz tam anlam\u0131yla otomatikle\u015fir, hata pay\u0131 azal\u0131r ve ekip verimlili\u011fi artar.<\/p>\n<h2>Pratik Bir Senaryo: Web Uygulamas\u0131 Altyap\u0131s\u0131n\u0131 Otomatikle\u015ftirmek<\/h2>\n<p>Teorik bilgileri peki\u015ftirmek ve konuyu daha anla\u015f\u0131l\u0131r k\u0131lmak ad\u0131na, ger\u00e7ek d\u00fcnya tabanl\u0131 bir senaryoyu ele alal\u0131m. Diyelim ki basit bir blog veya statik bir web sitesi i\u00e7in AWS \u00fczerinde temel bir altyap\u0131 kurmak istiyoruz. Bu altyap\u0131, bir sanal sunucu (EC2), bir g\u00fcvenlik grubu, statik web sitesi bar\u0131nd\u0131rma i\u00e7in bir S3 kovas\u0131 ve bir DNS kayd\u0131ndan (Route 53) olu\u015facak. T\u00fcm bu bile\u015fenleri Terraform ile tan\u0131mlayacak ve GitHub Actions arac\u0131l\u0131\u011f\u0131yla otomatik olarak da\u011f\u0131taca\u011f\u0131z.<\/p>\n<p><strong>Ad\u0131m 1: Terraform Proje Yap\u0131s\u0131<\/strong><\/p>\n<p>Proje dizinimizde a\u015fa\u011f\u0131daki dosyalar\u0131 olu\u015ftural\u0131m:<\/p>\n<ul>\n<li><code>main.tf<\/code>: Ana altyap\u0131 kaynak tan\u0131mlamalar\u0131.<\/li>\n<li><code>variables.tf<\/code>: De\u011fi\u015fken tan\u0131mlamalar\u0131.<\/li>\n<li><code>outputs.tf<\/code>: Da\u011f\u0131t\u0131m sonras\u0131 \u00e7\u0131kt\u0131lar\u0131n g\u00f6sterimi.<\/li>\n<\/ul>\n<p><strong><code>main.tf<\/code> (Ana Kaynak Tan\u0131mlamalar\u0131)<\/strong><\/p>\n<p>Bu dosya, EC2 \u00f6rne\u011fi, g\u00fcvenlik grubu, S3 kovas\u0131 ve iste\u011fe ba\u011fl\u0131 olarak Route 53 DNS kayd\u0131n\u0131 i\u00e7erecektir.<\/p>\n<pre><code>\n# AWS Sa\u011flay\u0131c\u0131s\u0131n\u0131 Tan\u0131mlama\nprovider \"aws\" {\n  region = var.aws_region\n}\n\n# Terraform State Y\u00f6netimi i\u00e7in S3 Backend\nterraform {\n  backend \"s3\" {\n    bucket         = \"my-web-app-terraform-state-bucket-12345\" # Benzersiz olmal\u0131\n    key            = \"prod\/webapp-infrastructure.tfstate\"\n    region         = \"us-east-1\" # Backend S3 kovas\u0131n\u0131n bulundu\u011fu b\u00f6lge\n    encrypt        = true\n    dynamodb_table = \"webapp-terraform-state-lock\"\n  }\n}\n\n# Web Sunucusu (EC2 Instance)\nresource \"aws_instance\" \"web_server\" {\n  ami           = var.ami_id\n  instance_type = var.instance_type\n  key_name      = var.key_pair_name\n  vpc_security_group_ids = [aws_security_group.web_sg.id]\n\n  tags = {\n    Name        = \"WebAppWebServer\"\n    Environment = \"Production\"\n  }\n}\n\n# G\u00fcvenlik Grubu (Security Group)\nresource \"aws_security_group\" \"web_sg\" {\n  name        = \"webapp_security_group\"\n  description = \"Allow HTTP, HTTPS and SSH inbound traffic\"\n  vpc_id      = var.vpc_id # Mevcut bir VPC ID'si\n\n  ingress {\n    description = \"HTTP from anywhere\"\n    from_port   = 80\n    to_port     = 80\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n\n  ingress {\n    description = \"HTTPS from anywhere\"\n    from_port   = 443\n    to_port     = 443\n    protocol    = \"tcp\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n\n  ingress {\n    description = \"SSH from your IP\"\n    from_port   = 22\n    to_port     = 22\n    protocol    = \"tcp\"\n    cidr_blocks = [\"${var.my_ip}\/32\"]\n  }\n\n  egress {\n    from_port   = 0\n    to_port     = 0\n    protocol    = \"-1\"\n    cidr_blocks = [\"0.0.0.0\/0\"]\n  }\n}\n\n# Statik Web Sitesi i\u00e7in S3 Kovas\u0131\nresource \"aws_s3_bucket\" \"website_bucket\" {\n  bucket = var.s3_website_bucket_name # Benzersiz ve d\u00fc\u015f\u00fck harfli olmal\u0131\n  acl    = \"public-read\"\n  policy = jsonencode({\n    Version = \"2012-10-17\"\n    Statement = [\n      {\n        Sid       = \"PublicReadGetObject\"\n        Effect    = \"Allow\"\n        Principal = \"*\"\n        Action    = [\"s3:GetObject\"]\n        Resource  = [\"arn:aws:s3:::${var.s3_website_bucket_name}\/*\"]\n      },\n    ]\n  })\n\n  website {\n    index_document = \"index.html\"\n    error_document = \"error.html\"\n  }\n\n  tags = {\n    Name        = \"WebAppWebsiteBucket\"\n    Environment = \"Production\"\n  }\n}\n\n# S3 kovas\u0131n\u0131 bir Terraform state kovas\u0131 olarak da kullanaca\u011f\u0131z\n# Bu y\u00fczden yukar\u0131daki backend blogu i\u00e7in de bir bucket tan\u0131mlamas\u0131 yapmal\u0131y\u0131z\nresource \"aws_s3_bucket\" \"terraform_state_for_backend\" {\n  bucket = \"my-web-app-terraform-state-bucket-12345\" # Backend'de kullan\u0131lanla ayn\u0131 isim\n  acl    = \"private\"\n  versioning {\n    enabled = true\n  }\n  server_side_encryption_configuration {\n    rule {\n      apply_server_side_encryption_by_default {\n        sse_algorithm = \"AES256\"\n      }\n    }\n  }\n}\n\nresource \"aws_dynamodb_table\" \"terraform_state_lock_for_backend\" {\n  name           = \"webapp-terraform-state-lock\" # Backend'de kullan\u0131lanla ayn\u0131 isim\n  billing_mode   = \"PAY_PER_REQUEST\"\n  hash_key       = \"LockID\"\n  attribute {\n    name = \"LockID\"\n    type = \"S\"\n  }\n}\n\n# Route 53 DNS Kayd\u0131 (\u0130ste\u011fe ba\u011fl\u0131, mevcut bir Hosted Zone gerektirir)\n# data \"aws_route53_zone\" \"selected\" {\n#   name         = var.domain_name\n#   private_zone = false\n# }\n\n# resource \"aws_route53_record\" \"www\" {\n#   zone_id = data.aws_route53_zone.selected.zone_id\n#   name    = \"www.${var.domain_name}\"\n#   type    = \"A\"\n\n#   alias {\n#     name                   = aws_s3_bucket.website_bucket.website_domain\n#     zone_id                = aws_s3_bucket.website_bucket.hosted_zone_id\n#     evaluate_target_health = true\n#   }\n# }\n    <\/pre>\n<p><\/code><\/p>\n<p><strong><code>variables.tf<\/code> (De\u011fi\u015fken Tan\u0131mlamalar\u0131)<\/strong><\/p>\n<pre><code>\nvariable \"aws_region\" {\n  description = \"AWS b\u00f6lgesi\"\n  type        = string\n  default     = \"us-east-1\"\n}\n\nvariable \"ami_id\" {\n  description = \"EC2 instance i\u00e7in Amazon Machine Image ID\"\n  type        = string\n  default     = \"ami-0abcdef1234567890\" # L\u00fctfen kendi b\u00f6lgeniz i\u00e7in ge\u00e7erli bir AMI ID kullan\u0131n\n}\n\nvariable \"instance_type\" {\n  description = \"EC2 instance tipi\"\n  type        = string\n  default     = \"t2.micro\"\n}\n\nvariable \"key_pair_name\" {\n  description = \"EC2'ye SSH eri\u015fimi i\u00e7in kullan\u0131lan anahtar \u00e7ifti ad\u0131\"\n  type        = string\n  default     = \"my-ec2-keypair\" # Mevcut bir anahtar \u00e7ifti ad\u0131 olmal\u0131\n}\n\nvariable \"vpc_id\" {\n  description = \"EC2 instance'\u0131n\u0131n ba\u015flat\u0131laca\u011f\u0131 VPC ID'si\"\n  type        = string\n  default     = \"vpc-0abcdef1234567890\" # Mevcut bir VPC ID'si olmal\u0131\n}\n\nvariable \"my_ip\" {\n  description = \"SSH eri\u015fimine izin verilecek IP adresi\"\n  type        = string\n  default     = \"0.0.0.0\" # Kendi genel IP adresinizi kullan\u0131n (\u00f6rn: \"XXX.XXX.XXX.XXX\")\n}\n\nvariable \"s3_website_bucket_name\" {\n  description = \"Statik web sitesi i\u00e7in S3 kovas\u0131 ad\u0131\"\n  type        = string\n  default     = \"my-unique-webapp-static-site-12345\" # Benzersiz olmal\u0131\n}\n\n# variable \"domain_name\" {\n#   description = \"Route 53 Hosted Zone i\u00e7in domain ad\u0131\"\n#   type        = string\n#   default     = \"example.com\" # Kendi domain ad\u0131n\u0131z\u0131 kullan\u0131n\n# }\n    <\/pre>\n<p><\/code><\/p>\n<p><strong><code>outputs.tf<\/code> (\u00c7\u0131kt\u0131 Tan\u0131mlamalar\u0131)<\/strong><\/p>\n<pre><code>\noutput \"web_server_public_ip\" {\n  description = \"Web sunucusunun genel IP adresi\"\n  value       = aws_instance.web_server.public_ip\n}\n\noutput \"s3_website_endpoint\" {\n  description = \"Statik web sitesi S3 kovas\u0131n\u0131n endpoint adresi\"\n  value       = aws_s3_bucket.website_bucket.website_endpoint\n}\n    <\/pre>\n<p><\/code><\/p>\n<p><strong>Ad\u0131m 2: GitHub Actions Entegrasyonu<\/strong><\/p>\n<p>Yukar\u0131daki Terraform kodunu GitHub deponuza ekleyin. Ard\u0131ndan, daha \u00f6nce g\u00f6sterilen GitHub Actions YAML dosyas\u0131n\u0131 (<code>.github\/workflows\/main.yml<\/code>) deponuza ekleyin. AWS kimlik bilgilerini GitHub Secrets olarak ayarlad\u0131\u011f\u0131n\u0131zdan emin olun. Bu senaryoda kullan\u0131lan <code>terraform init<\/code>, <code>plan<\/code> ve <code>apply<\/code> ad\u0131mlar\u0131, Terraform kodunuzu otomatik olarak AWS'e da\u011f\u0131tacakt\u0131r.<\/p>\n<p><strong>Vaka Analizi: K\u00fc\u00e7\u00fck Bir E-Ticaret Sitesi<\/strong><\/p>\n<p>Bir e-ticaret startup'\u0131 d\u00fc\u015f\u00fcnelim. Yeni bir \u00fcr\u00fcn lansman\u0131 \u00f6ncesinde, geli\u015ftirme, test ve \u00fcretim ortamlar\u0131n\u0131 h\u0131zla kurmalar\u0131 gerekiyor. Manuel olarak her ortam\u0131 tek tek yap\u0131land\u0131rmak, haftalar s\u00fcrebilir, tutars\u0131zl\u0131klara yol a\u00e7abilir ve lansman gecikmelerine neden olabilir. Bu startup, yukar\u0131daki gibi Terraform ve GitHub Actions entegrasyonunu kullanarak altyap\u0131 da\u011f\u0131t\u0131m\u0131n\u0131 otomatikle\u015ftirmeye karar verdi. Sonu\u00e7lar inan\u0131lmazd\u0131:<\/p>\n<ul>\n<li><strong>H\u0131z:<\/strong> Her yeni ortam, dakikalar i\u00e7inde tam olarak yap\u0131land\u0131r\u0131lm\u0131\u015f ve kullan\u0131ma haz\u0131r hale geldi.<\/li>\n<li><strong>Tutarl\u0131l\u0131k:<\/strong> Kod tabanl\u0131 altyap\u0131 sayesinde, geli\u015ftirme ortam\u0131ndaki sorunlar \u00fcretimde tekrarlanmad\u0131 \u00e7\u00fcnk\u00fc t\u00fcm ortamlar ayn\u0131 koddan t\u00fcretildi.<\/li>\n<li><strong>G\u00fcvenilirlik:<\/strong> Otomatikle\u015ftirilmi\u015f da\u011f\u0131t\u0131m s\u00fcre\u00e7leri, insan hatas\u0131n\u0131 ortadan kald\u0131rd\u0131 ve ba\u015far\u0131l\u0131 da\u011f\u0131t\u0131m oran\u0131n\u0131 \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rd\u0131.<\/li>\n<li><strong>Maliyet Etkinli\u011fi:<\/strong> Kullan\u0131lmayan test ortamlar\u0131, belirli bir s\u00fcre sonra otomatik olarak kapat\u0131ld\u0131 veya yok edildi, bu da AWS faturalar\u0131nda b\u00fcy\u00fck tasarruf sa\u011flad\u0131.<\/li>\n<\/ul>\n<p>Bu vaka analizi, IaC'nin ve CI\/CD'nin sadece b\u00fcy\u00fck \u015firketler i\u00e7in de\u011fil, ayn\u0131 zamanda \u00e7evik ve h\u0131zl\u0131 hareket etmesi gereken k\u00fc\u00e7\u00fck ekipler ve startup'lar i\u00e7in de ne kadar de\u011ferli oldu\u011funu a\u00e7\u0131k\u00e7a g\u00f6stermektedir. Altyap\u0131y\u0131 kod olarak y\u00f6netmek ve da\u011f\u0131t\u0131m\u0131 otomatikle\u015ftirmek, modern yaz\u0131l\u0131m geli\u015ftirmenin temel ta\u015f\u0131d\u0131r.<\/p>\n<h2>Geli\u015fmi\u015f Stratejiler ve En \u0130yi Uygulamalar<\/h2>\n<p>Terraform, AWS S3 ve GitHub Actions ile temel altyap\u0131 otomasyonunu kurduktan sonra, projelerinizi daha da \u00f6l\u00e7eklenebilir, g\u00fcvenli ve y\u00f6netilebilir hale getirmek i\u00e7in baz\u0131 geli\u015fmi\u015f stratejileri ve en iyi uygulamalar\u0131 de\u011ferlendirebilirsiniz.<\/p>\n<p><strong>1. Mod\u00fclerizasyon ve Yeniden Kullan\u0131labilirlik:<\/strong><\/p>\n<p>B\u00fcy\u00fck projelerde, t\u00fcm altyap\u0131y\u0131 tek bir <code>main.tf<\/code> dosyas\u0131nda tutmak h\u0131zla karma\u015f\u0131k hale gelebilir. Terraform mod\u00fclleri, kodunuzu mant\u0131ksal, yeniden kullan\u0131labilir birimlere ay\u0131rman\u0131za olanak tan\u0131r. \u00d6rne\u011fin, bir EC2 web sunucusu kurulumu, bir VPC veya bir veritaban\u0131 k\u00fcmesi i\u00e7in ayr\u0131 mod\u00fcller olu\u015fturabilirsiniz. Bu mod\u00fclleri, farkl\u0131 ortamlarda (dev, staging, prod) veya farkl\u0131 projelerde tekrar tekrar kullanabilirsiniz. Mod\u00fcller, kod tekrar\u0131n\u0131 (DRY - Don't Repeat Yourself) azalt\u0131r ve altyap\u0131 y\u00f6netiminizi daha d\u00fczenli hale getirir.<\/p>\n<pre><code>\n# main.tf dosyas\u0131nda bir mod\u00fcl\u00fc \u00e7a\u011f\u0131rma \u00f6rne\u011fi\nmodule \"web_app_servers\" {\n  source = \".\/modules\/web-server\" # Yerel bir mod\u00fcl yolu\n  \n  instance_type = \"t3.medium\"\n  ami_id        = var.ami_id\n  vpc_id        = var.vpc_id\n  # ... di\u011fer de\u011fi\u015fkenler\n}\n    <\/pre>\n<p><\/code><\/p>\n<p><strong>2. Ortamlar Aras\u0131 Y\u00f6netim (Dev, Staging, Prod):<\/strong><\/p>\n<p>Ger\u00e7ek d\u00fcnya uygulamalar\u0131nda, geli\u015ftirme, test (staging) ve \u00fcretim (production) gibi farkl\u0131 ortamlar bulunur. Bu ortamlar\u0131n her biri i\u00e7in ayr\u0131 Terraform state dosyalar\u0131 ve ayr\u0131 Terraform yap\u0131land\u0131rmalar\u0131 tutmak genellikle en iyi yakla\u015f\u0131md\u0131r. Her ortam i\u00e7in ayr\u0131 bir klas\u00f6r yap\u0131s\u0131 kullanabilir ve her klas\u00f6rde kendi <code>main.tf<\/code>, <code>variables.tf<\/code> ve <code>backend.tf<\/code> dosyalar\u0131n\u0131 bulundurabilirsiniz. GitHub Actions i\u015f ak\u0131\u015flar\u0131n\u0131zda, farkl\u0131 branch'lere (\u00f6rne\u011fin <code>dev<\/code>, <code>staging<\/code>, <code>main<\/code>) yap\u0131lan push'lar i\u00e7in farkl\u0131 ortamlar\u0131n da\u011f\u0131t\u0131m\u0131n\u0131 tetikleyebilirsiniz.<\/p>\n<p><strong>3. G\u00fcvenlik Entegrasyonu ve En Az Yetki Prensibi (Least Privilege):<\/strong><\/p>\n<ul>\n<li><strong>IAM Rolleri:<\/strong> GitHub Actions'\u0131n AWS kaynaklar\u0131n\u0131za eri\u015fmesi i\u00e7in kullan\u0131lan IAM kullan\u0131c\u0131s\u0131 yerine, AWS OIDC (OpenID Connect) ile GitHub Actions'a bir IAM rol\u00fc atamak daha g\u00fcvenli bir y\u00f6ntemdir. Bu sayede, uzun \u00f6m\u00fcrl\u00fc kimlik bilgilerine ihtiya\u00e7 duyulmaz.<\/li>\n<li><strong>KMS ile \u015eifreleme:<\/strong> AWS S3'teki Terraform state dosyan\u0131z\u0131 \u015fifrelemek i\u00e7in KMS (Key Management Service) kullanmak, hassas verilerinizi daha da g\u00fcvende tutar. S3 bucket yap\u0131land\u0131rman\u0131za bir KMS anahtar\u0131 ekleyerek bunu sa\u011flayabilirsiniz.<\/li>\n<li><strong>Secret Y\u00f6netimi:<\/strong> Veritaban\u0131 \u015fifreleri, API anahtarlar\u0131 gibi hassas bilgileri asla Terraform kodunuzda veya state dosyas\u0131nda a\u00e7\u0131k metin olarak saklamay\u0131n. Bunlar\u0131 AWS Secrets Manager veya HashiCorp Vault gibi \u00f6zel gizli y\u00f6netim \u00e7\u00f6z\u00fcmleriyle entegre edin ve Terraform'un bu ara\u00e7lardan dinamik olarak \u00e7ekmesini sa\u011flay\u0131n.<\/li>\n<\/ul>\n<p><strong>4. Terraform Kodu \u0130nceleme ve Kalite Kontrol\u00fc:<\/strong><\/p>\n<p>Terraform kodunuzu Git deponuza g\u00f6ndermeden \u00f6nce <code>terraform fmt<\/code> ile bi\u00e7imlendirin ve <code>terraform validate<\/code> ile s\u00f6zdizimi hatalar\u0131n\u0131 kontrol edin. Ayr\u0131ca, kod incelemeleri (pull request review) s\u0131ras\u0131nda, di\u011fer ekip \u00fcyelerinin Terraform plan \u00e7\u0131kt\u0131lar\u0131n\u0131 incelemesini sa\u011flayarak istenmeyen de\u011fi\u015fikliklerin \u00f6n\u00fcne ge\u00e7ebilirsiniz.<\/p>\n<p><strong>5. Geri Alma (Rollback) Stratejileri:<\/strong><\/p>\n<p>Her ne kadar otomasyon hata riskini azaltsa da, \u00fcretimde beklenmedik sorunlar ortaya \u00e7\u0131kabilir. Bu durumlarda, h\u0131zl\u0131 ve g\u00fcvenli bir \u015fekilde \u00f6nceki bir duruma geri d\u00f6nebilmek kritik \u00f6neme sahiptir. S3 bucket'\u0131n\u0131zda etkinle\u015ftirilen versiyonlama, state dosyan\u0131z\u0131n ge\u00e7mi\u015fini tutar. Yanl\u0131\u015f giden bir da\u011f\u0131t\u0131m durumunda, Terraform'u \u00f6nceki bir state dosyas\u0131 s\u00fcr\u00fcm\u00fcn\u00fc kullanarak yeniden \u00e7al\u0131\u015ft\u0131rmak bir geri alma stratejisi olabilir.<\/p>\n<div class=\"tip\">\n      Uzman \u0130pucu: B\u00fcy\u00fck altyap\u0131 de\u011fi\u015fikliklerinde, \u00f6nce k\u00fc\u00e7\u00fck bir de\u011fi\u015fikli\u011fi (canary deployment) belirli bir kullan\u0131c\u0131 grubuna da\u011f\u0131tmay\u0131 ve ba\u015far\u0131l\u0131 oldu\u011funu do\u011frulad\u0131ktan sonra t\u00fcm kullan\u0131c\u0131lara yaymay\u0131 d\u00fc\u015f\u00fcnebilirsiniz. Bu, riskleri minimize etmenin etkili bir yoludur.\n    <\/div>\n<p><strong>6. Maliyet Y\u00f6netimi ve Etiketleme (Tagging):<\/strong><\/p>\n<p>Bulut kaynaklar\u0131 maliyetli olabilir. Terraform ile olu\u015fturdu\u011funuz t\u00fcm kaynaklara tutarl\u0131 bir etiketleme stratejisi uygulay\u0131n. \u00d6rne\u011fin, her kayna\u011fa <code>Environment<\/code> (Dev, Prod), <code>Project<\/code>, <code>Owner<\/code> gibi etiketler ekleyin. Bu etiketler, AWS Maliyet Y\u00f6netimi ara\u00e7lar\u0131nda maliyetleri izlemenize, raporlaman\u0131za ve optimize etmenize yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<p>Bu geli\u015fmi\u015f stratejiler ve en iyi uygulamalar, altyap\u0131 otomasyon yolculu\u011funuzda kar\u015f\u0131la\u015fabilece\u011finiz zorluklar\u0131 a\u015fman\u0131za ve daha dayan\u0131kl\u0131, g\u00fcvenli ve verimli bir sistem kurman\u0131za yard\u0131mc\u0131 olacakt\u0131r. S\u00fcrekli \u00f6\u011frenme ve mevcut ara\u00e7lar\u0131 derinlemesine anlama, bu alandaki ba\u015far\u0131n\u0131n anahtar\u0131d\u0131r.<\/p>\n<h2>Sonu\u00e7: Altyap\u0131 Otomasyonu ile Gelece\u011fe Y\u00f6nelik Bir Ad\u0131m<\/h2>\n<p>Bu makale boyunca, modern bulut altyap\u0131s\u0131 y\u00f6netiminin temel ta\u015flar\u0131ndan olan Altyap\u0131 Kod Olarak (IaC) felsefesini, \u00f6zellikle de Terraform'un g\u00fcc\u00fcn\u00fc, AWS S3 Remote Backend ile state y\u00f6netiminin \u00f6nemini ve GitHub Actions ile entegre CI\/CD s\u00fcre\u00e7lerinin nas\u0131l kuruldu\u011funu detayl\u0131 bir \u015fekilde inceledik. G\u00f6rd\u00fck ki, manuel s\u00fcre\u00e7lerin getirdi\u011fi riskler ve verimsizlikler, otomasyon ara\u00e7lar\u0131 sayesinde kolayca a\u015f\u0131labilir ve geli\u015ftirme ekiplerine \u00f6nemli avantajlar sa\u011flanabilir.<\/p>\n<p>\u00d6zellikle, Terraform'un deklaratif yap\u0131s\u0131, altyap\u0131m\u0131z\u0131 kod olarak tan\u0131mlamam\u0131za ve versiyon kontrol alt\u0131nda tutmam\u0131za olanak tan\u0131rken, AWS S3'\u00fcn sa\u011flad\u0131\u011f\u0131 uzaktan state y\u00f6netimi, tak\u0131m \u00e7al\u0131\u015fmas\u0131n\u0131 kolayla\u015ft\u0131rm\u0131\u015f, state dosyas\u0131n\u0131n g\u00fcvenli\u011fini art\u0131rm\u0131\u015f ve versiyonlama \u00f6zellikleriyle geri alma senaryolar\u0131nda bize b\u00fcy\u00fck esneklik sunmu\u015ftur. DynamoDB ile entegrasyonu sayesinde state kilitleme mekanizmas\u0131, birden fazla kullan\u0131c\u0131n\u0131n ayn\u0131 anda de\u011fi\u015fiklik yapmas\u0131n\u0131 engelleyerek state dosyas\u0131n\u0131n bozulmas\u0131n\u0131n \u00f6n\u00fcne ge\u00e7mi\u015ftir. T\u00fcm bu altyap\u0131 tan\u0131mlamalar\u0131n\u0131 ve y\u00f6netimini GitHub Actions ile birle\u015ftirmek ise, kod de\u011fi\u015fikliklerinin otomatik olarak alg\u0131lan\u0131p, planlan\u0131p ve g\u00fcvenli bir \u015fekilde uygulanmas\u0131n\u0131 sa\u011flayarak, geli\u015ftiricilerin altyap\u0131 da\u011f\u0131t\u0131m s\u00fcre\u00e7lerine daha az zaman ay\u0131r\u0131p as\u0131l i\u015flerine odaklanmalar\u0131na imkan tan\u0131m\u0131\u015ft\u0131r.<\/p>\n<p>Altyap\u0131 otomasyonu, sadece da\u011f\u0131t\u0131m h\u0131z\u0131n\u0131 art\u0131rmakla kalmaz; ayn\u0131 zamanda tutarl\u0131l\u0131\u011f\u0131, g\u00fcvenilirli\u011fi ve \u00f6l\u00e7eklenebilirli\u011fi de beraberinde getirir. Bir web uygulamas\u0131 altyap\u0131s\u0131 \u00f6rne\u011finde g\u00f6sterildi\u011fi gibi, karma\u015f\u0131k bulut kaynaklar\u0131n\u0131 bile kod ile y\u00f6netmek, operasyonel y\u00fck\u00fc \u00f6nemli \u00f6l\u00e7\u00fcde azalt\u0131r ve ekiplerin yenili\u011fe daha fazla odaklanmas\u0131n\u0131 sa\u011flar. Geli\u015fmi\u015f stratejiler ve en iyi uygulamalar b\u00f6l\u00fcm\u00fcnde ele ald\u0131\u011f\u0131m\u0131z mod\u00fclerizasyon, g\u00fcvenlik entegrasyonlar\u0131 ve maliyet y\u00f6netimi gibi konular ise, otomasyon yolculu\u011funuzda kar\u015f\u0131la\u015fabilece\u011finiz zorluklara kar\u015f\u0131 size rehberlik edecek, daha sa\u011flam ve s\u00fcrd\u00fcr\u00fclebilir sistemler kurman\u0131za yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<p>Sonu\u00e7 olarak, Terraform, AWS S3 Remote Backend ve GitHub Actions \u00fc\u00e7l\u00fcs\u00fc, modern DevOps pratiklerinin merkezinde yer alan g\u00fc\u00e7l\u00fc bir kombinasyondur. Bu ara\u00e7lar\u0131 etkin bir \u015fekilde kullanarak, \u015firketler altyap\u0131lar\u0131n\u0131 daha \u00e7evik, hatas\u0131z ve maliyet etkin bir \u015fekilde y\u00f6netebilirler. Unutmay\u0131n, bu alandaki teknoloji s\u00fcrekli geli\u015fiyor; bu nedenle s\u00fcrekli \u00f6\u011frenmeye ve yeni ara\u00e7lar\u0131 ke\u015ffetmeye a\u00e7\u0131k olmak, sizi her zaman bir ad\u0131m \u00f6nde tutacakt\u0131r. Altyap\u0131 otomasyonu, sadece bir teknolojik ge\u00e7i\u015f de\u011fil, ayn\u0131 zamanda operasyonel m\u00fckemmelli\u011fe ve i\u015f \u00e7evikli\u011fine ula\u015fman\u0131n anahtar\u0131d\u0131r. \u015eimdiden bu ara\u00e7lar\u0131 denemeye ba\u015flayarak gelece\u011fin altyap\u0131 y\u00f6netimine y\u00f6nelik sa\u011flam bir ad\u0131m atabilirsiniz.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<ul>\n<li>\n        <strong>Soru 1: Terraform state dosyas\u0131 neden bu kadar hassast\u0131r ve g\u00fcvenli\u011fi neden \u00f6nemlidir?<\/strong><br \/>\n        <strong>Cevap:<\/strong> Terraform state dosyas\u0131, y\u00f6netti\u011fi t\u00fcm altyap\u0131 kaynaklar\u0131n\u0131n ger\u00e7ek zamanl\u0131 durumunu (ID'ler, konfig\u00fcrasyonlar, ili\u015fkiler) ve hatta baz\u0131 durumlarda hassas bilgileri (veritaban\u0131 \u015fifreleri, API anahtarlar\u0131) i\u00e7erebilir. Bu dosyan\u0131n yetkisiz ki\u015filerce ele ge\u00e7irilmesi ciddi g\u00fcvenlik ihlallerine yol a\u00e7abilir. Ayr\u0131ca, dosyan\u0131n bozulmas\u0131 veya kaybolmas\u0131, Terraform'un altyap\u0131n\u0131zla olan ba\u011flant\u0131s\u0131n\u0131 kaybetmesine ve altyap\u0131 y\u00f6netiminin fel\u00e7 olmas\u0131na neden olabilir. Bu y\u00fczden g\u00fcvenli, \u015fifrelenmi\u015f ve versiyonlanabilir bir yerde saklanmas\u0131 hayati \u00f6nem ta\u015f\u0131r.\n      <\/li>\n<li>\n        <strong>Soru 2: GitHub Actions yerine ba\u015fka CI\/CD ara\u00e7lar\u0131 kullanarak Terraform da\u011f\u0131t\u0131m\u0131 yapabilir miyim?<\/strong><br \/>\n        <strong>Cevap:<\/strong> Kesinlikle! GitHub Actions, GitHub ile derin entegrasyonu nedeniyle pop\u00fcler bir se\u00e7enektir, ancak Jenkins, GitLab CI\/CD, CircleCI, Travis CI, Bitbucket Pipelines veya AWS CodePipeline gibi bir\u00e7ok g\u00fc\u00e7l\u00fc alternatif bulunmaktad\u0131r. Terraform'un platformdan ba\u011f\u0131ms\u0131z yap\u0131s\u0131 sayesinde, \u00e7o\u011fu CI\/CD arac\u0131yla kolayca entegre edilebilir ve otomatik altyap\u0131 da\u011f\u0131t\u0131m\u0131 i\u00e7in kullan\u0131labilir. Se\u00e7im genellikle mevcut ekosisteminiz ve tercih etti\u011finiz \u00f6zellik setine ba\u011fl\u0131d\u0131r.\n      <\/li>\n<li>\n        <strong>Soru 3: AWS S3'te Terraform state dosyalar\u0131n\u0131 \u015fifrelemek i\u00e7in KMS kullanmak zorunlu mu?<\/strong><br \/>\n        <strong>Cevap:<\/strong> Hay\u0131r, zorunlu de\u011fildir ancak \u015fiddetle tavsiye edilir. S3 bucket'\u0131n\u0131zda versiyonlamay\u0131 etkinle\u015ftirdi\u011finizde, varsay\u0131lan olarak AES256 sunucu taraf\u0131 \u015fifrelemesi (SSE-S3) ile \u015fifrelenir. Ancak, AWS KMS (Key Management Service) ile \u015fifreleme (SSE-KMS) kullanmak, \u015fifreleme anahtarlar\u0131n\u0131z \u00fczerinde daha fazla kontrol, denetim ve merkezi y\u00f6netim imkan\u0131 sunar. Bu, \u00f6zellikle y\u00fcksek g\u00fcvenlik gerektiren ortamlar ve uyumluluk standartlar\u0131 i\u00e7in tercih edilen bir y\u00f6ntemdir.\n      <\/li>\n<li>\n        <strong>Soru 4: Terraform mod\u00fclleri ne i\u015fe yarar ve ne zaman kullanmal\u0131y\u0131m?<\/strong><br \/>\n        <strong>Cevap:<\/strong> Terraform mod\u00fclleri, altyap\u0131 kodunuzu tekrar kullan\u0131labilir, organize edilmi\u015f ve parametrele\u015ftirilebilir birimlere ay\u0131rman\u0131za olanak tan\u0131r. Bir mod\u00fcl, bir veya daha fazla kaynak tan\u0131m\u0131n\u0131 kapsayan bir klas\u00f6rden ibarettir. Mod\u00fclleri kullanman\u0131n temel faydalar\u0131 \u015funlard\u0131r: kod tekrar\u0131n\u0131 azaltma (DRY prensibi), karma\u015f\u0131kl\u0131\u011f\u0131 y\u00f6netme, ekipler aras\u0131nda tutarl\u0131l\u0131\u011f\u0131 art\u0131rma ve test edilebilirli\u011fi geli\u015ftirme. Altyap\u0131n\u0131z b\u00fcy\u00fcd\u00fck\u00e7e, farkl\u0131 ortamlar i\u00e7in benzer yap\u0131land\u0131rmalar\u0131 tekrarlaman\u0131z gerekti\u011finde veya ekip \u00fcyeleri aras\u0131nda standartla\u015ft\u0131r\u0131lm\u0131\u015f altyap\u0131 bile\u015fenleri sa\u011flamak istedi\u011finizde mod\u00fclleri kullanmal\u0131s\u0131n\u0131z.\n      <\/li>\n<li>\n        <strong>Soru 5: Altyap\u0131 da\u011f\u0131t\u0131m\u0131nda <code>terraform apply -auto-approve<\/code> komutunu kullanmak g\u00fcvenli midir?<\/strong><br \/>\n        <strong>Cevap:<\/strong> <code>terraform apply -auto-approve<\/code> komutu, plan \u00e7\u0131kt\u0131s\u0131n\u0131 incelemeden ve manuel onay almadan de\u011fi\u015fiklikleri do\u011frudan uygular. Geli\u015ftirme veya test ortamlar\u0131nda otomatik da\u011f\u0131t\u0131mlar i\u00e7in kullan\u0131\u015fl\u0131 olabilir. Ancak, \u00fcretim ortamlar\u0131nda bu komutu do\u011frudan kullanmak dikkatli bir yakla\u015f\u0131m de\u011fildir. Genellikle, bir <code>pull request<\/code> a\u015famas\u0131nda <code>terraform plan<\/code> \u00e7\u0131kt\u0131s\u0131n\u0131 g\u00f6zden ge\u00e7irmek ve ard\u0131ndan, de\u011fi\u015fiklikler onayland\u0131ktan sonra (\u00f6rne\u011fin <code>main<\/code> branch'e birle\u015ftirildi\u011finde) manuel veya ko\u015fullu bir <code>apply<\/code> tetiklemek daha g\u00fcvenli ve kontroll\u00fc bir yakla\u015f\u0131md\u0131r. Bu, istenmeyen veya hatal\u0131 de\u011fi\u015fikliklerin \u00fcretim ortam\u0131na ula\u015fmas\u0131n\u0131 engellemek i\u00e7in bir g\u00fcvenlik katman\u0131 sa\u011flar.\n      <\/li>\n<\/ul><\/div>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Modern yaz\u0131l\u0131m d\u00fcnyas\u0131nda altyap\u0131 y\u00f6netimi zorlay\u0131c\u0131 ve zaman al\u0131c\u0131 bir s\u00fcre\u00e7 olabilir. Bu makale, Terraform, AWS S3 ve&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1401],"tags":[],"class_list":{"0":"post-32802","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-git","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu<\/title>\n<meta name=\"description\" content=\"Modern yaz\u0131l\u0131m d\u00fcnyas\u0131nda altyap\u0131 y\u00f6netimi zorlay\u0131c\u0131 ve zaman al\u0131c\u0131 bir s\u00fcre\u00e7 olabilir. Bu makale, Terraform, AWS S3 ve GitHub Actions&#039;\u0131 kullanarak altyap\u0131n\u0131z\u0131 nas\u0131l otomatikle\u015ftirece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131klayacakt\u0131r.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu\" \/>\n<meta property=\"og:description\" content=\"Modern yaz\u0131l\u0131m d\u00fcnyas\u0131nda altyap\u0131 y\u00f6netimi zorlay\u0131c\u0131 ve zaman al\u0131c\u0131 bir s\u00fcre\u00e7 olabilir. Bu makale, Terraform, AWS S3 ve GitHub Actions&#039;\u0131 kullanarak altyap\u0131n\u0131z\u0131 nas\u0131l otomatikle\u015ftirece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131klayacakt\u0131r.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-26T01:31:36+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"29 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu\",\"datePublished\":\"2025-10-26T01:31:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/\"},\"wordCount\":4609,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Git\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/\",\"name\":\"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-26T01:31:36+00:00\",\"description\":\"Modern yaz\u0131l\u0131m d\u00fcnyas\u0131nda altyap\u0131 y\u00f6netimi zorlay\u0131c\u0131 ve zaman al\u0131c\u0131 bir s\u00fcre\u00e7 olabilir. Bu makale, Terraform, AWS S3 ve GitHub Actions'\u0131 kullanarak altyap\u0131n\u0131z\u0131 nas\u0131l otomatikle\u015ftirece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131klayacakt\u0131r.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu","description":"Modern yaz\u0131l\u0131m d\u00fcnyas\u0131nda altyap\u0131 y\u00f6netimi zorlay\u0131c\u0131 ve zaman al\u0131c\u0131 bir s\u00fcre\u00e7 olabilir. Bu makale, Terraform, AWS S3 ve GitHub Actions'\u0131 kullanarak altyap\u0131n\u0131z\u0131 nas\u0131l otomatikle\u015ftirece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131klayacakt\u0131r.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/","og_locale":"tr_TR","og_type":"article","og_title":"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu","og_description":"Modern yaz\u0131l\u0131m d\u00fcnyas\u0131nda altyap\u0131 y\u00f6netimi zorlay\u0131c\u0131 ve zaman al\u0131c\u0131 bir s\u00fcre\u00e7 olabilir. Bu makale, Terraform, AWS S3 ve GitHub Actions'\u0131 kullanarak altyap\u0131n\u0131z\u0131 nas\u0131l otomatikle\u015ftirece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131klayacakt\u0131r.","og_url":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-26T01:31:36+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"29 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu","datePublished":"2025-10-26T01:31:36+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/"},"wordCount":4609,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Git"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/","url":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/","name":"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-26T01:31:36+00:00","description":"Modern yaz\u0131l\u0131m d\u00fcnyas\u0131nda altyap\u0131 y\u00f6netimi zorlay\u0131c\u0131 ve zaman al\u0131c\u0131 bir s\u00fcre\u00e7 olabilir. Bu makale, Terraform, AWS S3 ve GitHub Actions'\u0131 kullanarak altyap\u0131n\u0131z\u0131 nas\u0131l otomatikle\u015ftirece\u011finizi ad\u0131m ad\u0131m a\u00e7\u0131klayacakt\u0131r.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/terraform-s3-ve-github-actions-ile-altyapi-otomasyonu\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Terraform, S3 ve GitHub Actions ile Altyap\u0131 Otomasyonu"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32802","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=32802"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32802\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=32802"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=32802"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=32802"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}