{"id":37859,"date":"2026-01-17T10:41:02","date_gmt":"2026-01-17T07:41:02","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=37859"},"modified":"2026-01-17T10:41:02","modified_gmt":"2026-01-17T07:41:02","slug":"ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/","title":{"rendered":"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#8217;lar\u0131 Olu\u015fturma Rehberi"},"content":{"rendered":"<p><body><\/p>\n<h2>Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#8217;lar\u0131 Olu\u015fturma Rehberi<\/h2>\n<h3>Giri\u015f: Altyap\u0131y\u0131 Kod Olarak Y\u00f6netmek (IaC) ve Chef<\/h3>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn h\u0131zl\u0131 tempolu yaz\u0131l\u0131m geli\u015ftirme ve da\u011f\u0131t\u0131m d\u00fcnyas\u0131nda, altyap\u0131y\u0131 manuel olarak y\u00f6netmek giderek daha s\u00fcrd\u00fcr\u00fclemez hale gelmektedir. Sunucu kurulumlar\u0131, yaz\u0131l\u0131m ba\u011f\u0131ml\u0131l\u0131klar\u0131, yap\u0131land\u0131rma dosyalar\u0131 ve hizmetlerin ba\u015flat\u0131lmas\u0131 gibi g\u00f6revlerin her seferinde elle yap\u0131lmas\u0131 zaman al\u0131c\u0131, hataya a\u00e7\u0131k ve tekrarlanamazd\u0131r. \u0130\u015fte tam bu noktada &#8220;Altyap\u0131y\u0131 Kod Olarak&#8221; (Infrastructure as Code &#8211; IaC) kavram\u0131 devreye girer. IaC, altyap\u0131 bile\u015fenlerini ve yap\u0131land\u0131rmalar\u0131n\u0131 kod olarak tan\u0131mlayarak, versiyon kontrol sistemleri arac\u0131l\u0131\u011f\u0131yla y\u00f6netilmesini, test edilmesini ve otomatikle\u015ftirilmesini sa\u011flar. Bu sayede, geli\u015ftirme, test ve \u00fcretim ortamlar\u0131 aras\u0131nda tutarl\u0131l\u0131k sa\u011flan\u0131r, da\u011f\u0131t\u0131m s\u00fcre\u00e7leri h\u0131zlan\u0131r ve insan kaynakl\u0131 hatalar minimize edilir.<\/p>\n<p>Chef, bu IaC felsefesini benimseyen g\u00fc\u00e7l\u00fc bir otomasyon platformudur. Ruby tabanl\u0131 bir DSL (Domain Specific Language) kullanarak sunucular\u0131n nas\u0131l yap\u0131land\u0131r\u0131laca\u011f\u0131n\u0131, yaz\u0131l\u0131mlar\u0131n nas\u0131l kurulaca\u011f\u0131n\u0131 ve hizmetlerin nas\u0131l y\u00f6netilece\u011fini tan\u0131mlaman\u0131za olanak tan\u0131r. Chef ile altyap\u0131n\u0131z\u0131 bir kez kod olarak tan\u0131mlad\u0131\u011f\u0131n\u0131zda, bu tan\u0131m\u0131 y\u00fczlerce sunucuya tutarl\u0131 bir \u015fekilde uygulayabilir, zaman ve emekten tasarruf edebilirsiniz. Chef&#8217;in sundu\u011fu tekrarlanabilirlik, \u00f6l\u00e7eklenebilirlik ve tutarl\u0131l\u0131k, modern DevOps yakla\u015f\u0131mlar\u0131n\u0131n temelini olu\u015fturur.<\/p>\n<p>Bu makalede, Ubuntu i\u015fletim sistemi \u00fczerinde basit Chef cookbook&#8217;lar\u0131 olu\u015fturmay\u0131, bunlar\u0131 yerel olarak test etmeyi ve altyap\u0131n\u0131z\u0131 y\u00f6netmek i\u00e7in kullanmay\u0131 ad\u0131m ad\u0131m \u00f6\u011frenece\u011fiz. Chef&#8217;in temel bile\u015fenlerini anlayacak, basit bir web sunucusu kurulumunu otomatikle\u015ftirecek ve cookbook&#8217;lar\u0131n\u0131z\u0131 daha dinamik hale getirmek i\u00e7in nitelikler (attributes) ve \u015fablonlar (templates) gibi geli\u015fmi\u015f \u00f6zelliklerini ke\u015ffedece\u011fiz.<\/p>\n<h3>Chef Temelleri: Mimari ve Bile\u015fenler<\/h3>\n<p>Chef&#8217;i etkili bir \u015fekilde kullanabilmek i\u00e7in temel mimarisini ve ana bile\u015fenlerini anlamak \u00f6nemlidir. Chef, genellikle \u00fc\u00e7 ana bile\u015fenden olu\u015fan bir istemci-sunucu modelinde \u00e7al\u0131\u015f\u0131r:<\/p>\n<h4>Chef Mimarisi<\/h4>\n<p>1.  <strong>Chef Workstation (\u0130\u015f \u0130stasyonu):<\/strong><br \/>\n    *   Geli\u015ftiricilerin veya sistem y\u00f6neticilerinin Chef cookbook&#8217;lar\u0131n\u0131 yazd\u0131\u011f\u0131, test etti\u011fi ve Chef Server ile etkile\u015fim kurdu\u011fu makinedir.<br \/>\n    *   Chef Development Kit (ChefDK) burada y\u00fckl\u00fcd\u00fcr. ChefDK, <code>chef<\/code>, <code>knife<\/code>, <code>berkshelf<\/code>, <code>test-kitchen<\/code> gibi gerekli t\u00fcm ara\u00e7lar\u0131 i\u00e7erir.<br \/>\n    *   Cookbook&#8217;lar burada olu\u015fturulur ve Chef Server&#8217;a y\u00fcklenmeden \u00f6nce test edilir.<\/p>\n<p>2.  <strong>Chef Server:<\/strong><br \/>\n    *   T\u00fcm cookbook&#8217;lar\u0131, politikalar\u0131, d\u00fc\u011f\u00fcm (node) yap\u0131land\u0131rmalar\u0131n\u0131 ve d\u00fc\u011f\u00fcmlerin mevcut durumunu depolayan merkezi bir depodur.<br \/>\n    *   D\u00fc\u011f\u00fcmlerin yap\u0131land\u0131rma isteklerini al\u0131r ve bunlara uygun cookbook&#8217;lar\u0131 ve tarifleri (recipes) g\u00f6nderir.<br \/>\n    *   A\u00e7\u0131k kaynak Chef Server, ticari Chef Automate veya bulut tabanl\u0131 Hosted Chef olarak kullan\u0131labilir.<\/p>\n<p>3.  <strong>Chef Node (D\u00fc\u011f\u00fcm):<\/strong><br \/>\n    *   Chef Server taraf\u0131ndan y\u00f6netilen sunuculard\u0131r (fiziksel, sanal veya bulut tabanl\u0131).<br \/>\n    *   Her d\u00fc\u011f\u00fcmde <code>chef-client<\/code> ad\u0131 verilen bir ajan (agent) \u00e7al\u0131\u015f\u0131r.<br \/>\n    *   <code>chef-client<\/code>, belirli aral\u0131klarla veya manuel olarak \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131nda Chef Server ile ileti\u015fim kurar, kendisine atanan run list&#8217;i (\u00e7al\u0131\u015ft\u0131rma listesi) al\u0131r ve bu listeye g\u00f6re kendi yap\u0131land\u0131rmas\u0131n\u0131 g\u00fcnceller.<br \/>\n    *   Ohai ad\u0131 verilen bir ara\u00e7, d\u00fc\u011f\u00fcm hakk\u0131ndaki sistem bilgilerini (i\u015fletim sistemi, IP adresi, bellek vb.) toplar ve Chef Server&#8217;a g\u00f6nderir.<\/p>\n<h4>Temel Chef Bile\u015fenleri<\/h4>\n<p>Chef, altyap\u0131y\u0131 tan\u0131mlamak i\u00e7in \u00e7e\u015fitli bile\u015fenleri kullan\u0131r:<\/p>\n<p>1.  <strong>Resource (Kaynak):<\/strong><br \/>\n    *   Chef&#8217;in temel yap\u0131 ta\u015f\u0131d\u0131r. Bir kayna\u011f\u0131n belirli bir durumda (state) olmas\u0131n\u0131 garanti eden bir soyutlamad\u0131r.<br \/>\n    *   \u00d6rnekler: <code>package<\/code> (bir paketin y\u00fckl\u00fc olmas\u0131n\u0131 sa\u011flar), <code>service<\/code> (bir hizmetin \u00e7al\u0131\u015f\u0131yor olmas\u0131n\u0131 sa\u011flar), <code>file<\/code> (bir dosyan\u0131n belirli bir i\u00e7eri\u011fe sahip olmas\u0131n\u0131 sa\u011flar), <code>user<\/code> (bir kullan\u0131c\u0131n\u0131n var olmas\u0131n\u0131 sa\u011flar), <code>directory<\/code> (bir dizinin var olmas\u0131n\u0131 sa\u011flar).<br \/>\n    *   Her resource, bir t\u00fcr (type), bir isim (name) ve bir dizi aksiyon (action) ile niteliklere (properties) sahiptir. \u00d6rne\u011fin: <code>package 'nginx' do action :install end<\/code><\/p>\n<p>2.  <strong>Recipe (Tarif):<\/strong><br \/>\n    *   Bir veya daha fazla kayna\u011f\u0131n (resource) bir araya gelerek belirli bir yap\u0131land\u0131rma hedefine ula\u015fmas\u0131n\u0131 sa\u011flayan Ruby kodudur.<br \/>\n    *   Cookbook&#8217;lar\u0131n kalbidir. Bir tarif, bir web sunucusunun kurulumu, bir veritaban\u0131n\u0131n yap\u0131land\u0131r\u0131lmas\u0131 veya bir uygulaman\u0131n da\u011f\u0131t\u0131m\u0131 gibi belirli bir g\u00f6revi tan\u0131mlar.<br \/>\n    *   <code>recipes\/default.rb<\/code> genellikle bir cookbook&#8217;un ana tarifidir.<\/p>\n<p>3.  <strong>Cookbook:<\/strong><br \/>\n    *   \u0130lgili tarifleri, dosyalar\u0131, \u015fablonlar\u0131, nitelikleri ve di\u011fer bile\u015fenleri i\u00e7eren organize bir dizin yap\u0131s\u0131d\u0131r.<br \/>\n    *   Belirli bir g\u00f6revi veya uygulama grubunu y\u00f6netmek i\u00e7in gerekli t\u00fcm bilgileri bar\u0131nd\u0131r\u0131r. \u00d6rne\u011fin, bir <code>webserver<\/code> cookbook&#8217;u Nginx veya Apache kurulumu ve yap\u0131land\u0131rmas\u0131 i\u00e7in t\u00fcm tarifleri i\u00e7erebilir.<\/p>\n<p>4.  <strong>Attribute (Nitelik):<\/strong><br \/>\n    *   Cookbook&#8217;lar\u0131n davran\u0131\u015f\u0131n\u0131 dinamik olarak de\u011fi\u015ftirmek i\u00e7in kullan\u0131lan de\u011fi\u015fkenlerdir.<br \/>\n    *   \u00d6rne\u011fin, bir web sunucusu cookbook&#8217;u i\u00e7in varsay\u0131lan HTTP portunu (80) bir nitelik olarak tan\u0131mlayabilir ve bu niteli\u011fi farkl\u0131 d\u00fc\u011f\u00fcmler i\u00e7in farkl\u0131 de\u011ferlerle ge\u00e7ersiz k\u0131labilirsiniz.<br \/>\n    *   <code>attributes\/default.rb<\/code> dosyas\u0131nda tan\u0131mlan\u0131r.<\/p>\n<p>5.  <strong>Template (\u015eablon):<\/strong><br \/>\n    *   Dinamik olarak olu\u015fturulmas\u0131 gereken yap\u0131land\u0131rma dosyalar\u0131 i\u00e7in kullan\u0131l\u0131r.<br \/>\n    *   ERB (Embedded Ruby) s\u00f6zdizimini kullanarak, niteliklerden veya di\u011fer kaynaklardan gelen verileri bir dosyaya yerle\u015ftirebilirsiniz.<br \/>\n    *   <code>templates\/default\/<\/code> dizininde bulunur ve genellikle <code>.erb<\/code> uzant\u0131s\u0131na sahiptir.<\/p>\n<p>6.  <strong>File (Dosya):<\/strong><br \/>\n    *   Bir d\u00fc\u011f\u00fcme kopyalanmas\u0131 gereken statik dosyalar i\u00e7in kullan\u0131l\u0131r.<br \/>\n    *   <code>files\/default\/<\/code> dizininde bulunur.<\/p>\n<p>7.  <strong>Ohai:<\/strong><br \/>\n    *   Chef d\u00fc\u011f\u00fcmlerinde \u00e7al\u0131\u015fan ve sistem hakk\u0131nda \u00e7e\u015fitli bilgiler (i\u015fletim sistemi, a\u011f aray\u00fczleri, CPU, bellek vb.) toplayan bir ara\u00e7t\u0131r.<br \/>\n    *   Bu bilgiler Chef Server&#8217;a g\u00f6nderilir ve tariflerde ko\u015fullu mant\u0131k olu\u015fturmak i\u00e7in kullan\u0131labilir (\u00f6rne\u011fin, &#8220;yaln\u0131zca Ubuntu sunucular\u0131nda \u015funu yap&#8221;).<\/p>\n<h3>Kurulum ve Ortam Haz\u0131rl\u0131\u011f\u0131 (Ubuntu Workstation \u00dczerinde)<\/h3>\n<p>Chef cookbook&#8217;lar\u0131 geli\u015ftirmeye ba\u015flamadan \u00f6nce, Chef Workstation&#8217;\u0131n\u0131z\u0131 kurman\u0131z gerekir. Ubuntu \u00fczerinde bu i\u015flem olduk\u00e7a basittir.<\/p>\n<h4>1. Chef Development Kit (ChefDK) Kurulumu<\/h4>\n<p>ChefDK, Chef geli\u015ftirme i\u00e7in ihtiyac\u0131n\u0131z olan t\u00fcm ara\u00e7lar\u0131 (Chef Client, Knife, Test Kitchen, Berkshelf vb.) tek bir pakette sunar.<\/p>\n<p>\u00d6ncelikle, Chef&#8217;in APT deposunu sisteminize eklememiz gerekiyor:<\/p>\n<pre><code class=\"language-bash\">curl https:\/\/packages.chef.io\/chef.asc | sudo apt-key add -\necho \"deb https:\/\/packages.chef.io\/repos\/apt\/current $(lsb_release -cs) main\" | sudo tee \/etc\/apt\/sources.list.d\/chef.list\nsudo apt update<\/code><\/pre>\n<p>\u015eimdi ChefDK&#8217;y\u0131 kurabiliriz:<\/p>\n<pre><code class=\"language-bash\">sudo apt install chefdk<\/code><\/pre>\n<p>Kurulum tamamland\u0131ktan sonra, <code>chef<\/code> komutunun \u00e7al\u0131\u015f\u0131p \u00e7al\u0131\u015fmad\u0131\u011f\u0131n\u0131 kontrol edebilirsiniz:<\/p>\n<pre><code class=\"language-bash\">chef -v<\/code><\/pre>\n<p>Bu komut, y\u00fckl\u00fc Chef s\u00fcr\u00fcm\u00fcn\u00fc g\u00f6stermelidir.<\/p>\n<h4>2. \u0130lk Chef Deponuzu Olu\u015fturma<\/h4>\n<p>Cookbook&#8217;lar\u0131n\u0131z\u0131 ve di\u011fer Chef yap\u0131land\u0131rma dosyalar\u0131n\u0131z\u0131 d\u00fczenli tutmak i\u00e7in bir &#8220;Chef deposu&#8221; (Chef repo) olu\u015fturmak iyi bir uygulamad\u0131r. Bu, genellikle bir Git deposu olarak y\u00f6netilir.<\/p>\n<pre><code class=\"language-bash\">mkdir ~\/chef-repo\ncd ~\/chef-repo\nchef generate app . # Mevcut dizinde bir Chef uygulamas\u0131 yap\u0131s\u0131 olu\u015fturur<\/code><\/pre>\n<p>Bu komut, <code>chef-repo<\/code> dizini i\u00e7inde temel bir Chef proje yap\u0131s\u0131 olu\u015fturacakt\u0131r: <code>cookbooks<\/code>, <code>data_bags<\/code>, <code>environments<\/code>, <code>roles<\/code>, <code>policyfiles<\/code> gibi dizinler.<\/p>\n<h4>3. \u0130lk Cookbook&#8217;unuzu Olu\u015fturma<\/h4>\n<p>\u015eimdi <code>webserver<\/code> ad\u0131nda basit bir cookbook olu\u015ftural\u0131m. Bu cookbook, Nginx web sunucusunu kuracak ve yap\u0131land\u0131racakt\u0131r.<\/p>\n<p><code>chef-repo<\/code> dizininizin i\u00e7inde oldu\u011funuzdan emin olun ve a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">chef generate cookbook cookbooks\/webserver<\/code><\/pre>\n<p>Bu komut, <code>cookbooks\/webserver<\/code> dizini alt\u0131nda standart bir cookbook yap\u0131s\u0131 olu\u015fturacakt\u0131r:<\/p>\n<pre><code class=\"language-\">webserver\/\n\u251c\u2500\u2500 Berksfile\n\u251c\u2500\u2500 CHANGELOG.md\n\u251c\u2500\u2500 metadata.rb\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 recipes\/\n\u2502   \u2514\u2500\u2500 default.rb\n\u251c\u2500\u2500 test\/\n\u2502   \u2514\u2500\u2500 integration\/\n\u2502       \u2514\u2500\u2500 default\/\n\u2502           \u2514\u2500\u2500 default_test.rb\n\u2514\u2500\u2500 attributes\/\n    \u2514\u2500\u2500 default.rb<\/code><\/pre>\n<p>*   <code>recipes\/default.rb<\/code>: Bu, cookbook&#8217;un ana tarifini i\u00e7erecek dosyad\u0131r.<br \/>\n*   <code>metadata.rb<\/code>: Cookbook hakk\u0131nda ad, s\u00fcr\u00fcm, a\u00e7\u0131klama ve ba\u011f\u0131ml\u0131l\u0131klar gibi bilgileri i\u00e7erir.<br \/>\n*   <code>attributes\/default.rb<\/code>: Cookbook i\u00e7in varsay\u0131lan nitelikleri tan\u0131mlar.<br \/>\n*   <code>test\/<\/code>: Test Kitchen ve InSpec testleri i\u00e7in dizin.<\/p>\n<h3>Basit Bir Web Sunucusu Cookbook&#8217;u Olu\u015fturma (Pratik \u00d6rnek)<\/h3>\n<p>\u015eimdi <code>webserver<\/code> cookbook&#8217;umuzu Nginx&#8217;i kuracak ve basit bir &#8220;Merhaba D\u00fcnya&#8221; sayfas\u0131 sunacak \u015fekilde d\u00fczenleyelim.<\/p>\n<h4>Hedefimiz:<\/h4>\n<p>1.  Nginx paketini kurmak.<br \/>\n2.  Nginx hizmetinin ba\u015flat\u0131ld\u0131\u011f\u0131ndan ve sistem ba\u015flang\u0131c\u0131nda etkinle\u015ftirildi\u011finden emin olmak.<br \/>\n3.  Basit bir <code>index.html<\/code> dosyas\u0131 olu\u015fturmak.<\/p>\n<h4>1. <code>recipes\/default.rb<\/code> Dosyas\u0131n\u0131 D\u00fczenleme<\/h4>\n<p><code>cookbooks\/webserver\/recipes\/default.rb<\/code> dosyas\u0131n\u0131 a\u00e7\u0131n ve i\u00e7eri\u011fini a\u015fa\u011f\u0131daki gibi de\u011fi\u015ftirin:<\/p>\n<pre><code class=\"language-ruby\">#\n<h2>Cookbook:: webserver<\/h2>\n<h2>Recipe:: default<\/h2>\n<h2># Copyright:: 2023, The Authors, All Rights Reserved.<\/h2>\n\n<h2>Nginx paketinin y\u00fckl\u00fc oldu\u011fundan emin ol<\/h2>\npackage 'nginx' do\n  action :install\nend\n\n<h2>Nginx hizmetinin \u00e7al\u0131\u015f\u0131r durumda ve sistem ba\u015flang\u0131c\u0131nda etkin oldu\u011fundan emin ol<\/h2>\nservice 'nginx' do\n  action [:start, :enable]\nend\n\n<h2>\/var\/www\/html\/index.nginx-debian.html dosyas\u0131n\u0131 olu\u015ftur ve i\u00e7eri\u011fini yaz<\/h2>\nfile '\/var\/www\/html\/index.nginx-debian.html' do\n  content ''\n  mode '0644'\n  owner 'www-data'\n  group 'www-data'\nend\n\n<h2>Nginx yap\u0131land\u0131rma dosyas\u0131n\u0131 de\u011fi\u015ftirmek isterseniz (iste\u011fe ba\u011fl\u0131)<\/h2>\n<h2>template '\/etc\/nginx\/sites-available\/default' do<\/h2>\n<h2>source 'nginx.conf.erb'<\/h2>\n<h2>#  variables(<\/h2>\n<h2>#    port: node['webserver']['port']<\/h2>\n<h2>#  )<\/h2>\n<h2>notifies :reload, 'service[nginx]', :immediately<\/h2>\n<h2>end<\/code><\/pre>\n<\/h2>\n<p>Bu tarifte \u00fc\u00e7 ana kaynak (resource) kullan\u0131yoruz:<\/p>\n<p>*   <code>package 'nginx'<\/code>: Bu kaynak, <code>nginx<\/code> paketinin sistemde y\u00fckl\u00fc olmas\u0131n\u0131 sa\u011flar. <code>action :install<\/code> ile y\u00fckleme i\u015flemini belirtiriz. Chef, paketin zaten y\u00fckl\u00fc olup olmad\u0131\u011f\u0131n\u0131 kontrol eder ve yaln\u0131zca gerekliyse y\u00fckler (idempotency).<br \/>\n*   <code>service 'nginx'<\/code>: Bu kaynak, <code>nginx<\/code> hizmetinin <code>[:start, :enable]<\/code> aksiyonlar\u0131yla hem ba\u015flat\u0131lmas\u0131n\u0131 hem de sistem ba\u015flang\u0131c\u0131nda otomatik olarak ba\u015flamas\u0131 i\u00e7in etkinle\u015ftirilmesini sa\u011flar.<br \/>\n*   <code>file '\/var\/www\/html\/index.nginx-debian.html'<\/code>: Bu kaynak, belirtilen yolda bir dosya olu\u015fturur veya var olan\u0131 g\u00fcnceller. <code>content<\/code> niteli\u011fi ile dosyan\u0131n i\u00e7eri\u011fini belirleriz. <code>mode<\/code>, <code>owner<\/code> ve <code>group<\/code> nitelikleri ile dosya izinlerini ve sahipli\u011fini ayarlar\u0131z. Nginx&#8217;in varsay\u0131lan sayfa yolu <code>index.nginx-debian.html<\/code> oldu\u011fu i\u00e7in bu dosyay\u0131 hedefliyoruz.<\/p>\n<h4>2. Cookbook&#8217;u Yerel Olarak Test Etme (Chef Zero Modu)<\/h4>\n<p>Cookbook&#8217;umuzu Chef Server&#8217;a y\u00fcklemeden veya ger\u00e7ek bir d\u00fc\u011f\u00fcme da\u011f\u0131tmadan \u00f6nce yerel olarak test edebiliriz. Chef&#8217;in &#8220;zero modu&#8221; (<code>-z<\/code> veya <code>--local-mode<\/code>) tam da bunun i\u00e7in tasarlanm\u0131\u015ft\u0131r. Chef Zero, ge\u00e7ici bir Chef Server gibi davran\u0131r ve cookbook&#8217;lar\u0131 yerel sisteminizde \u00e7al\u0131\u015ft\u0131r\u0131r.<\/p>\n<p><code>chef-repo<\/code> dizininizin i\u00e7inde oldu\u011funuzdan emin olun ve a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">sudo chef-client --local-mode --runlist 'recipe[webserver]'\n<h2>veya daha k\u0131sas\u0131:<\/h2>\nsudo chef-client -z -o webserver<\/code><\/pre>\n<p>*   <code>sudo<\/code>: Nginx kurulumu ve dosya yazma i\u015flemleri root yetkisi gerektirdi\u011fi i\u00e7in <code>sudo<\/code> kullan\u0131yoruz.<br \/>\n*   <code>-z<\/code> veya <code>--local-mode<\/code>: Chef&#8217;i zero modunda \u00e7al\u0131\u015ft\u0131r\u0131r.<br \/>\n*   <code>-o webserver<\/code> veya <code>--runlist 'recipe[webserver]'<\/code>: <code>webserver<\/code> cookbook&#8217;unun <code>default<\/code> tarifini \u00e7al\u0131\u015ft\u0131rma listesine ekler. (<code>default<\/code> tarifini belirtmeye gerek yoktur, \u00e7\u00fcnk\u00fc cookbook ad\u0131 varsay\u0131lan olarak <code>default<\/code> tarifini \u00e7a\u011f\u0131r\u0131r.)<\/p>\n<p>Komut \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131nda, Chef, Nginx&#8217;i kuracak, hizmeti ba\u015flatacak ve <code>index.nginx-debian.html<\/code> dosyas\u0131n\u0131 olu\u015fturacakt\u0131r. Konsolda, Chef&#8217;in her bir kayna\u011f\u0131 ba\u015far\u0131yla i\u015fledi\u011fini g\u00f6steren \u00e7\u0131kt\u0131lar g\u00f6receksiniz.<\/p>\n<h4>3. Do\u011frulama<\/h4>\n<p>Chef \u00e7al\u0131\u015ft\u0131ktan sonra, web sunucusunun ba\u015far\u0131yla kuruldu\u011funu do\u011frulayal\u0131m:<\/p>\n<p>1.  <strong>Nginx hizmetinin durumunu kontrol edin:<\/strong><\/p>\n<pre><code class=\"language-bash\">systemctl status nginx<\/code><\/pre>\n<p>    \u00c7\u0131kt\u0131da <code>active (running)<\/code> ibaresini g\u00f6rmelisiniz.<\/p>\n<p>2.  <strong>Web sayfas\u0131n\u0131 kontrol edin:<\/strong><br \/>\n    Web taray\u0131c\u0131n\u0131z\u0131 a\u00e7\u0131n ve <code>http:\/\/localhost<\/code> adresine gidin.<br \/>\n    `<code> mesaj\u0131n\u0131 i\u00e7eren sayfan\u0131z\u0131 g\u00f6rmelisiniz.<\/p>\n<p>Tebrikler! \u0130lk basit Chef cookbook'unuzu ba\u015far\u0131yla olu\u015fturdunuz ve yerel sisteminizde \u00e7al\u0131\u015ft\u0131rd\u0131n\u0131z.<\/p>\n<h3>Cookbook'u Geli\u015ftirme: Attribute, Template ve File Kullan\u0131m\u0131<\/h3>\n<p>Cookbook'lar\u0131m\u0131z\u0131 daha esnek ve dinamik hale getirmek i\u00e7in nitelikleri (attributes), \u015fablonlar\u0131 (templates) ve statik dosyalar\u0131 (files) kullanabiliriz.<\/p>\n<h4>1. Attribute Kullan\u0131m\u0131: Nginx Portunu \u00d6zelle\u015ftirme<\/h4>\n<p>\u015eu anda Nginx varsay\u0131lan olarak 80. portta \u00e7al\u0131\u015f\u0131yor. Diyelim ki farkl\u0131 bir portta \u00e7al\u0131\u015fmas\u0131n\u0131 istiyoruz veya bu portu bir nitelik olarak yap\u0131land\u0131r\u0131labilir hale getirmek istiyoruz.<\/p>\n<p><\/code>cookbooks\/webserver\/attributes\/default.rb<code> dosyas\u0131n\u0131 a\u00e7\u0131n ve a\u015fa\u011f\u0131daki i\u00e7eri\u011fi ekleyin:<\/p>\n<pre><code class=\"language-ruby\">#\n<h2>Cookbook:: webserver<\/h2>\n<h2>Attribute:: default<\/h2>\n<h2># Copyright:: 2023, The Authors, All Rights Reserved.<\/h2>\n\ndefault['webserver']['port'] = 80\ndefault['webserver']['welcome_message'] = 'Chef ile Altyapi Yonetimi Harika!'<\/code><\/pre>\n<p>Burada <\/code>webserver<code> cookbook'u i\u00e7in iki nitelik tan\u0131mlad\u0131k: <\/code>port<code> ve <\/code>welcome_message<code>. <\/code>default<code> \u00f6n eki, bu niteliklerin varsay\u0131lan de\u011ferler oldu\u011funu belirtir.<\/p>\n<p>\u015eimdi bu niteli\u011fi <\/code>recipes\/default.rb<code> tarifimizde kullanal\u0131m. Nginx'in yap\u0131land\u0131rma dosyas\u0131n\u0131 (\u00f6rne\u011fin <\/code>\/etc\/nginx\/sites-available\/default<code>) de\u011fi\u015ftirmemiz gerekecek. Bunun i\u00e7in bir \u015fablon kullanaca\u011f\u0131z.<\/p>\n<h4>2. Template Kullan\u0131m\u0131: Dinamik Nginx Yap\u0131land\u0131rmas\u0131 ve Kar\u015f\u0131lama Sayfas\u0131<\/h4>\n<p>Nginx'in varsay\u0131lan yap\u0131land\u0131rma dosyas\u0131n\u0131 de\u011fi\u015ftirmek ve <\/code>index.html<code> i\u00e7eri\u011fini dinamik hale getirmek i\u00e7in \u015fablonlar\u0131 kullanaca\u011f\u0131z.<\/p>\n<h5>Ad\u0131m 1: Nginx Yap\u0131land\u0131rma \u015eablonu Olu\u015fturma<\/h5>\n<p><\/code>cookbooks\/webserver\/templates\/default\/<code> dizini olu\u015fturun (e\u011fer yoksa) ve i\u00e7ine <\/code>nginx.conf.erb<code> ad\u0131nda bir dosya olu\u015fturun:<\/p>\n<pre><code class=\"language-bash\">mkdir -p cookbooks\/webserver\/templates\/default\/<\/code><\/pre>\n<p><\/code>cookbooks\/webserver\/templates\/default\/nginx.conf.erb<code> dosyas\u0131n\u0131 a\u00e7\u0131n ve a\u015fa\u011f\u0131daki i\u00e7eri\u011fi ekleyin:<\/p>\n<pre><code class=\"language-erb\">server {\n    listen <%= node['webserver']['port'] %> default_server;\n    listen [::]:<%= node['webserver']['port'] %> default_server;\n\n    root \/var\/www\/html;\n\n    index index.html index.htm index.nginx-debian.html;\n\n    server_name _;\n\n    location \/ {\n        try_files $uri $uri\/ =404;\n    }\n}<\/code><\/pre>\n<p>Bu \u015fablonda, Ruby'nin ERB s\u00f6zdizimini (<\/code><%= ... %><code>) kullanarak <\/code>node[&#8216;webserver&#8217;][&#8216;port&#8217;]<code> niteli\u011fini Nginx <\/code>listen<code> direktifine yerle\u015ftirdik. Chef, bu \u015fablonu i\u015fledi\u011finde, <\/code>node[&#8216;webserver&#8217;][&#8216;port&#8217;]<code> ifadesinin yerine <\/code>attributes\/default.rb<code> dosyas\u0131nda tan\u0131mlad\u0131\u011f\u0131m\u0131z de\u011feri (varsay\u0131lan olarak 80) koyacakt\u0131r.<\/p>\n<h5>Ad\u0131m 2: Kar\u015f\u0131lama Sayfas\u0131 \u015eablonu Olu\u015fturma<\/h5>\n<p>Ayn\u0131 dizinde <\/code>index.html.erb<code> ad\u0131nda bir dosya daha olu\u015ftural\u0131m:<\/p>\n<p><\/code>cookbooks\/webserver\/templates\/default\/index.html.erb<code><\/p>\n<pre><code class=\"language-erb\"><!DOCTYPE html>\n<html>\n<head>\n    <title>Chef Nginx Web Server<\/title>\n    <style>\n        body {\n            font-family: Arial, sans-serif;\n            text-align: center;\n            margin-top: 50px;\n            background-color: #f0f0f0;\n            color: #333;\n        }\n        h1 {\n            color: #007bff;\n        }\n        p {\n            font-size: 1.2em;\n        }\n    <\/style>\n<\/head>\n<body>\n    \n    <p>Bu sayfa Chef taraf\u0131ndan otomatik olarak olu\u015fturulmu\u015ftur.<\/p>\n    <p>Nginx portu: <strong><%= node['webserver']['port'] %><\/strong><\/p>\n    <p>Sunucu zaman\u0131: <%= Time.now.strftime(\"%Y-%m-%d %H:%M:%S\") %><\/p>\n<\/body>\n<\/html><\/code><\/pre>\n<p>Bu \u015fablonda, <\/code>welcome_message<code> niteli\u011fini ve <\/code>port<code> niteli\u011fini kullanarak dinamik bir kar\u015f\u0131lama sayfas\u0131 olu\u015fturuyoruz. Ayr\u0131ca, Ruby'nin <\/code>Time.now<code> fonksiyonunu kullanarak sunucunun g\u00fcncel zaman\u0131n\u0131 da ekliyoruz.<\/p>\n<h5>Ad\u0131m 3: Tarifimizi G\u00fcncelleme<\/h5>\n<p>\u015eimdi <\/code>cookbooks\/webserver\/recipes\/default.rb<code> dosyam\u0131z\u0131 bu \u015fablonlar\u0131 kullanacak \u015fekilde g\u00fcncelleyelim:<\/p>\n<pre><code class=\"language-ruby\">#\n<h2>Cookbook:: webserver<\/h2>\n<h2>Recipe:: default<\/h2>\n<h2># Copyright:: 2023, The Authors, All Rights Reserved.<\/h2>\n\n<h2>Nginx paketinin y\u00fckl\u00fc oldu\u011fundan emin ol<\/h2>\npackage 'nginx' do\n  action :install\nend\n\n<h2>Nginx hizmetinin \u00e7al\u0131\u015f\u0131r durumda ve sistem ba\u015flang\u0131c\u0131nda etkin oldu\u011fundan emin ol<\/h2>\nservice 'nginx' do\n  action [:start, :enable]\nend\n\n<h2>Nginx yap\u0131land\u0131rma dosyas\u0131n\u0131 \u015fablondan olu\u015ftur<\/h2>\ntemplate '\/etc\/nginx\/sites-available\/default' do\n  source 'nginx.conf.erb'\n  mode '0644'\n  owner 'root'\n  group 'root'\n  variables(\n    port: node['webserver']['port'] # Nitelikleri \u015fablona de\u011fi\u015fken olarak ge\u00e7ir\n  )\n  # Yap\u0131land\u0131rma de\u011fi\u015fti\u011finde Nginx hizmetini yeniden y\u00fckle\n  notifies :reload, 'service[nginx]', :immediately\nend\n\n<h2>Nginx varsay\u0131lan siteyi etkinle\u015ftir (e\u011fer daha \u00f6nce yap\u0131lmad\u0131ysa)<\/h2>\nlink '\/etc\/nginx\/sites-enabled\/default' do\n  to '\/etc\/nginx\/sites-available\/default'\n  not_if { ::File.exist?('\/etc\/nginx\/sites-enabled\/default') }\n  notifies :reload, 'service[nginx]', :immediately\nend\n\n\n<h2>Kar\u015f\u0131lama sayfas\u0131n\u0131 \u015fablondan olu\u015ftur<\/h2>\ntemplate '\/var\/www\/html\/index.html' do # Art\u0131k index.nginx-debian.html yerine index.html kullan\u0131yoruz\n  source 'index.html.erb'\n  mode '0644'\n  owner 'www-data'\n  group 'www-data'\n  variables(\n    welcome_message: node['webserver']['welcome_message'],\n    port: node['webserver']['port']\n  )\nend\n\n<h2>\u00d6nceki index.nginx-debian.html dosyas\u0131n\u0131 kald\u0131r (iste\u011fe ba\u011fl\u0131 ama iyi bir pratik)<\/h2>\nfile '\/var\/www\/html\/index.nginx-debian.html' do\n  action :delete\n  only_if { ::File.exist?('\/var\/www\/html\/index.nginx-debian.html') }\nend<\/code><\/pre>\n<p><strong>De\u011fi\u015fikliklerin A\u00e7\u0131klamas\u0131:<\/strong><\/p>\n<p>*   <\/code>template<code> kaynaklar\u0131n\u0131 kullanarak <\/code>nginx.conf.erb<code> ve <\/code>index.html.erb<code> \u015fablonlar\u0131n\u0131 ilgili yollara kopyal\u0131yoruz.<br \/>\n*   <\/code>variables<code> blo\u011fu ile nitelikleri \u015fablona de\u011fi\u015fken olarak iletiyoruz.<br \/>\n*   <\/code>notifies :reload, &#8216;service[nginx]&#8217;, :immediately<code> ifadesi, Nginx yap\u0131land\u0131rma dosyas\u0131 de\u011fi\u015fti\u011finde Nginx hizmetini hemen yeniden y\u00fcklemesini sa\u011flar. Bu, Chef'in \"notification\" mekanizmas\u0131d\u0131r ve kaynaklar aras\u0131ndaki ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00f6netmek i\u00e7in \u00e7ok g\u00fc\u00e7l\u00fcd\u00fcr.<br \/>\n*   Nginx'in <\/code>sites-available<code> dizinindeki yap\u0131land\u0131rmay\u0131 <\/code>sites-enabled<code> dizinine ba\u011flayarak etkinle\u015ftiriyoruz.<br \/>\n*   \u00d6nceki statik <\/code>file<code> kayna\u011f\u0131n\u0131 kald\u0131rd\u0131k ve yerine <\/code>template<code> kulland\u0131k. Ayr\u0131ca eski <\/code>index.nginx-debian.html<code> dosyas\u0131n\u0131 siliyoruz.<\/p>\n<h4>3. File Kullan\u0131m\u0131: Statik Bir Favicon Ekleme<\/h4>\n<p>Cookbook'unuza statik bir resim, CSS dosyas\u0131 veya ba\u015fka bir ikili dosya eklemek isterseniz <\/code>files<code> dizinini kullanabilirsiniz.<\/p>\n<h5>Ad\u0131m 1: Favicon Dosyas\u0131 Ekleme<\/h5>\n<p><\/code>cookbooks\/webserver\/files\/default\/<code> dizini olu\u015fturun (e\u011fer yoksa) ve i\u00e7ine <\/code>favicon.ico<code> ad\u0131nda bir dosya yerle\u015ftirin. Bu dosyay\u0131 internetten bulabilir veya kendiniz olu\u015fturabilirsiniz. \u00d6rne\u011fin, basit bir ikon dosyas\u0131:<\/p>\n<pre><code class=\"language-bash\">mkdir -p cookbooks\/webserver\/files\/default\/\n<h2>Buraya kendi favicon.ico dosyan\u0131z\u0131 yerle\u015ftirin.<\/h2>\n<h2>\u00d6rne\u011fin, internetten indirdi\u011finiz bir dosyay\u0131 buraya kopyalayabilirsiniz.<\/h2>\n<h2>cp ~\/Downloads\/favicon.ico cookbooks\/webserver\/files\/default\/<\/code><\/pre>\n<\/h2>\n<h5>Ad\u0131m 2: Tarifimizi G\u00fcncelleme<\/h5>\n<p><\/code>cookbooks\/webserver\/recipes\/default.rb<code> dosyam\u0131za <\/code>favicon.ico<code> dosyas\u0131n\u0131 web sunucusunun k\u00f6k dizinine kopyalamak i\u00e7in bir <\/code>cookbook_file<code> kayna\u011f\u0131 ekleyelim:<\/p>\n<pre><code class=\"language-ruby\"># ... (\u00f6nceki kodlar) ...\n\n<h2>Statik favicon dosyas\u0131n\u0131 kopyala<\/h2>\ncookbook_file '\/var\/www\/html\/favicon.ico' do\n  source 'favicon.ico' # files\/default\/favicon.ico dosyas\u0131n\u0131 i\u015faret eder\n  mode '0644'\n  owner 'www-data'\n  group 'www-data'\nend<\/code><\/pre>\n<h4>4. Yerel Olarak Test Etme ve Do\u011frulama<\/h4>\n<p>T\u00fcm bu de\u011fi\u015fikliklerden sonra, cookbook'umuzu tekrar yerel modda \u00e7al\u0131\u015ft\u0131ral\u0131m:<\/p>\n<pre><code class=\"language-bash\">sudo chef-client -z -o webserver<\/code><\/pre>\n<p>Chef'in \u00e7\u0131kt\u0131s\u0131nda Nginx yap\u0131land\u0131rma dosyas\u0131n\u0131n, <\/code>index.html<code> dosyas\u0131n\u0131n ve <\/code>favicon.ico<code> dosyas\u0131n\u0131n g\u00fcncellendi\u011fini g\u00f6rmelisiniz. Ayr\u0131ca Nginx hizmetinin yeniden y\u00fcklendi\u011fini de belirtmelidir.<\/p>\n<p>\u015eimdi taray\u0131c\u0131n\u0131zdan <\/code>http:\/\/localhost<code> adresine tekrar gidin:<\/p>\n<p>*   Yeni dinamik kar\u015f\u0131lama mesaj\u0131n\u0131 ve Nginx portunu i\u00e7eren sayfan\u0131z\u0131 g\u00f6rmelisiniz.<br \/>\n*   Taray\u0131c\u0131n\u0131z\u0131n sekmesinde favicon'un g\u00f6r\u00fcnd\u00fc\u011f\u00fcnden emin olun.<br \/>\n*   E\u011fer portu de\u011fi\u015ftirmek isterseniz, <\/code>cookbooks\/webserver\/attributes\/default.rb<code> dosyas\u0131ndaki <\/code>default[&#8216;webserver&#8217;][&#8216;port&#8217;] = 80<code> sat\u0131r\u0131n\u0131 <\/code>default[&#8216;webserver&#8217;][&#8216;port&#8217;] = 8080<code> gibi bir de\u011ferle de\u011fi\u015ftirin ve <\/code>chef-client<code>'\u0131 tekrar \u00e7al\u0131\u015ft\u0131r\u0131n. Nginx art\u0131k yeni portta hizmet verecektir (eski portta \u00e7al\u0131\u015fmayacakt\u0131r).<\/p>\n<h3>Cookbook'lar\u0131 Test Etme (Test Kitchen ve InSpec ile)<\/h3>\n<p>Cookbook'lar karma\u015f\u0131kla\u015ft\u0131k\u00e7a, de\u011fi\u015fikliklerin beklenen \u015fekilde \u00e7al\u0131\u015ft\u0131\u011f\u0131ndan emin olmak i\u00e7in test yapmak hayati \u00f6nem ta\u015f\u0131r. Chef ekosistemi, cookbook'lar\u0131 test etmek i\u00e7in g\u00fc\u00e7l\u00fc ara\u00e7lar sunar: Test Kitchen ve InSpec.<\/p>\n<p>*   <strong>Test Kitchen:<\/strong> Cookbook'lar\u0131 farkl\u0131 i\u015fletim sistemi ve platform kombinasyonlar\u0131nda (\u00f6rne\u011fin, Ubuntu 20.04, CentOS 7) izole bir ortamda (Docker, Vagrant, bulut sa\u011flay\u0131c\u0131lar) test etmenizi sa\u011flar.<br \/>\n*   <strong>InSpec:<\/strong> Altyap\u0131n\u0131z\u0131n g\u00fcvenlik ve uyumluluk durumunu tan\u0131mlamak ve do\u011frulamak i\u00e7in kullan\u0131lan bir denetim ve test \u00e7er\u00e7evesidir.<\/p>\n<h4>1. Test Kitchen Ortam\u0131n\u0131 Haz\u0131rlama<\/h4>\n<p>Cookbook'unuzu olu\u015fturdu\u011funuzda, <\/code>chef generate cookbook<code> komutu otomatik olarak bir <\/code>.kitchen.yml<code> dosyas\u0131 ve temel InSpec testleri i\u00e7eren bir <\/code>test\/integration\/default\/default_test.rb<code> dosyas\u0131 olu\u015fturur.<\/p>\n<p><\/code>.kitchen.yml<code> dosyas\u0131, Test Kitchen'\u0131n hangi s\u00fcr\u00fcc\u00fcy\u00fc (driver - \u00f6rn: <\/code>dokken<code> for Docker, <\/code>vagrant<code> for Vagrant), hangi platformlar\u0131 (i\u015fletim sistemleri) ve hangi test s\u00fcitlerini kullanaca\u011f\u0131n\u0131 tan\u0131mlar.<\/p>\n<p><\/code>cookbooks\/webserver\/.kitchen.yml<code> dosyas\u0131n\u0131 a\u00e7\u0131n. Varsay\u0131lan olarak \u015f\u00f6yle bir \u015fey g\u00f6rmelisiniz:<\/p>\n<pre><code class=\"language-yaml\">---\ndriver:\n  name: dokken\n\ntransport:\n  name: dokken\n\nverifier:\n  name: inspec\n\nplatforms:\n  - name: ubuntu-22.04\n  # - name: almalinux-8\n\nsuites:\n  - name: default\n    run_list:\n      - recipe[webserver::default]\n    verifier:\n      inspec_tests:\n        - test\/integration\/default\n    attributes:<\/code><\/pre>\n<p>Bu yap\u0131land\u0131rma, Test Kitchen'\u0131n Docker kullanarak Ubuntu 22.04 \u00fczerinde testleri \u00e7al\u0131\u015ft\u0131rmas\u0131n\u0131 sa\u011flar.<\/p>\n<h4>2. InSpec Testleri Yazma<\/h4>\n<p><\/code>cookbooks\/webserver\/test\/integration\/default\/default_test.rb<code> dosyas\u0131n\u0131 a\u00e7\u0131n ve i\u00e7eri\u011fini Nginx kurulumumuzu do\u011frulayacak \u015fekilde g\u00fcncelleyin:<\/p>\n<pre><code class=\"language-ruby\"># InSpec testleri Ruby tabanl\u0131d\u0131r ve altyap\u0131n\u0131z\u0131n beklenen durumda olup olmad\u0131\u011f\u0131n\u0131 do\u011frular.\n\n<h2>Nginx paketinin y\u00fckl\u00fc olup olmad\u0131\u011f\u0131n\u0131 kontrol et<\/h2>\ndescribe package('nginx') do\n  it { should be_installed }\nend\n\n<h2>Nginx hizmetinin \u00e7al\u0131\u015f\u0131r durumda ve etkin olup olmad\u0131\u011f\u0131n\u0131 kontrol et<\/h2>\ndescribe service('nginx') do\n  it { should be_installed } # Nginx hizmetinin y\u00fckl\u00fc oldu\u011funu kontrol eder\n  it { should be_enabled }   # Sistem ba\u015flang\u0131c\u0131nda etkin olup olmad\u0131\u011f\u0131n\u0131 kontrol eder\n  it { should be_running }   # \u015eu anda \u00e7al\u0131\u015f\u0131yor olup olmad\u0131\u011f\u0131n\u0131 kontrol eder\nend\n\n<h2>Nginx yap\u0131land\u0131rma dosyas\u0131n\u0131n varl\u0131\u011f\u0131n\u0131 ve i\u00e7eri\u011fini kontrol et<\/h2>\ndescribe file('\/etc\/nginx\/sites-available\/default') do\n  it { should exist }\n  its('content') { should match \/listen #{attribute('port')} default_server;\/ } # Nitelikten gelen portu kontrol et\nend\n\n<h2>Nginx sites-enabled linkinin varl\u0131\u011f\u0131n\u0131 kontrol et<\/h2>\ndescribe file('\/etc\/nginx\/sites-enabled\/default') do\n  it { should be_symlink }\n  it { should be_linked_to '\/etc\/nginx\/sites-available\/default' }\nend\n\n<h2>Kar\u015f\u0131lama sayfas\u0131n\u0131n varl\u0131\u011f\u0131n\u0131 ve i\u00e7eri\u011fini kontrol et<\/h2>\ndescribe file('\/var\/www\/html\/index.html') do\n  it { should exist }\n  its('content') { should match \/<h1>#{attribute('welcome_message')}<\\\/h1>\/ } # Nitelikten gelen mesaj\u0131 kontrol et\n  its('content') { should match \/Nginx portu: <strong>#{attribute('port')}<\\\/strong>\/ }\nend\n\n<h2>Favicon dosyas\u0131n\u0131n varl\u0131\u011f\u0131n\u0131 kontrol et<\/h2>\ndescribe file('\/var\/www\/html\/favicon.ico') do\n  it { should exist }\n  it { should be_file }\n  it { should be_owned_by 'www-data' }\nend\n\n<h2>Nginx'in belirli bir portta dinledi\u011fini kontrol et<\/h2>\ndescribe port(attribute('port')) do\n  it { should be_listening }\nend<\/code><\/pre>\n<p>Bu InSpec testleri, cookbook'umuzun yapt\u0131\u011f\u0131 her \u015feyi do\u011fruluyor: paket kurulumu, hizmet durumu, dosya varl\u0131\u011f\u0131 ve i\u00e7eri\u011fi, ba\u011flant\u0131lar ve hatta a\u011f portu dinleme durumu. <\/code>attribute(&#8216;port&#8217;)<code> ve <\/code>attribute(&#8216;welcome_message&#8217;)<code> kullanarak testleri cookbook nitelikleriyle senkronize ediyoruz. Bu nitelikler <\/code>.kitchen.yml<code> dosyas\u0131ndaki <\/code>attributes<code> blo\u011fundan veya do\u011frudan <\/code>node<code> objesinden al\u0131n\u0131r.<\/p>\n<p><\/code>.kitchen.yml<code> dosyas\u0131ndaki <\/code>suites<code> alt\u0131ndaki <\/code>attributes<code> blo\u011funa, testler s\u0131ras\u0131nda kullan\u0131lacak nitelikleri ekleyelim:<\/p>\n<pre><code class=\"language-yaml\">suites:\n  - name: default\n    run_list:\n      - recipe[webserver::default]\n    verifier:\n      inspec_tests:\n        - test\/integration\/default\n    attributes:\n      webserver:\n        port: 80 # attributes\/default.rb dosyas\u0131ndaki de\u011feriyle e\u015fle\u015fmeli\n        welcome_message: 'Chef ile Altyapi Yonetimi Harika!' # attributes\/default.rb dosyas\u0131ndaki de\u011feriyle e\u015fle\u015fmeli<\/code><\/pre>\n<h4>3. Testleri \u00c7al\u0131\u015ft\u0131rma<\/h4>\n<p><\/code>chef-repo<code> dizininizin i\u00e7inde oldu\u011funuzdan emin olun ve a\u015fa\u011f\u0131daki komutlar\u0131 \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<p>*   <strong>Test ortam\u0131n\u0131 olu\u015ftur ve cookbook'u uygula (converge):<\/strong><\/p>\n<pre><code class=\"language-bash\">kitchen converge<\/code><\/pre>\n<p>    Bu komut, Docker container'\u0131n\u0131 ba\u015flatacak, Chef Client'\u0131 y\u00fckleyecek ve <\/code>webserver::default<code> tarifini uygulayacakt\u0131r.<\/p>\n<p>*   <strong>Uygulanan cookbook'u do\u011frula (verify):<\/strong><\/p>\n<pre><code class=\"language-bash\">kitchen verify<\/code><\/pre>\n<p>    Bu komut, container \u00fczerinde InSpec testlerini \u00e7al\u0131\u015ft\u0131racak ve t\u00fcm testlerin ge\u00e7ip ge\u00e7medi\u011fini bildirecektir. E\u011fer bir test ba\u015far\u0131s\u0131z olursa, nerede hata oldu\u011funu g\u00f6steren ayr\u0131nt\u0131l\u0131 bir \u00e7\u0131kt\u0131 al\u0131rs\u0131n\u0131z.<\/p>\n<p>*   <strong>T\u00fcm ad\u0131mlar\u0131 tek seferde \u00e7al\u0131\u015ft\u0131r (test):<\/strong><\/p>\n<pre><code class=\"language-bash\">kitchen test<\/code><\/pre>\n<p>    Bu komut <\/code>create<code>, <\/code>converge<code>, <\/code>verify<code> ve <\/code>destroy<code> ad\u0131mlar\u0131n\u0131 s\u0131ras\u0131yla \u00e7al\u0131\u015ft\u0131r\u0131r.<\/p>\n<p>*   <strong>Test ortam\u0131n\u0131 yok et (destroy):<\/strong><\/p>\n<pre><code class=\"language-bash\">kitchen destroy<\/code><\/pre>\n<p>    Testleriniz bittikten sonra, olu\u015fturulan Docker container'\u0131n\u0131 temizlemek i\u00e7in bu komutu kullan\u0131n.<\/p>\n<p>Test Kitchen ve InSpec kullanarak, cookbook'lar\u0131n\u0131z\u0131n beklendi\u011fi gibi \u00e7al\u0131\u015ft\u0131\u011f\u0131ndan ve altyap\u0131n\u0131z\u0131n tutarl\u0131 bir durumda oldu\u011fundan emin olabilirsiniz. Bu, geli\u015ftirme s\u00fcrecinde g\u00fcveni art\u0131r\u0131r ve \u00fcretim ortam\u0131na da\u011f\u0131t\u0131m riskini azalt\u0131r.<\/p>\n<h3>Cookbook'u Chef Server'a Y\u00fckleme ve Node'lara Uygulama<\/h3>\n<p>\u015eimdiye kadar cookbook'umuzu yerel olarak test ettik. Ger\u00e7ek d\u00fcnya senaryolar\u0131nda, cookbook'lar\u0131 bir Chef Server'a y\u00fckler ve ard\u0131ndan sunucular\u0131n\u0131z\u0131 (node'lar\u0131) bu server \u00fczerinden y\u00f6netirsiniz.<\/p>\n<p>Bu b\u00f6l\u00fcm, bir Chef Server'\u0131n kurulu oldu\u011funu ve Chef Workstation'\u0131n\u0131z\u0131n bu server ile ileti\u015fim kuracak \u015fekilde yap\u0131land\u0131r\u0131ld\u0131\u011f\u0131n\u0131 varsaymaktad\u0131r (genellikle <\/code>.chef\/config.rb<code> ve <\/code>.chef\/YOUR_ORGANIZATION_NAME-validator.pem<code> dosyalar\u0131 ile). E\u011fer bir Chef Server'\u0131n\u0131z yoksa, Hosted Chef kullanabilir veya yerel bir Chef Server kurabilirsiniz (ancak bu makalenin kapsam\u0131 d\u0131\u015f\u0131ndad\u0131r).<\/p>\n<h4>1. Chef Server Ba\u011flant\u0131s\u0131n\u0131 Yap\u0131land\u0131rma (\u00d6zet)<\/h4>\n<p>Chef Server ile ileti\u015fim kurmak i\u00e7in Workstation'\u0131n\u0131zda <\/code>.chef<code> dizini ve i\u00e7inde <\/code>config.rb<code> dosyas\u0131 bulunmal\u0131d\u0131r. Bu dosya, Chef Server URL'sini, kurulu\u015f ad\u0131n\u0131 ve kimlik do\u011frulama anahtar\u0131n\u0131n yolunu i\u00e7erir.<\/p>\n<pre><code class=\"language-ruby\"># ~\/chef-repo\/.chef\/config.rb (\u00d6rnek)\ncurrent_dir = File.dirname(__FILE__)\nlog_level                :info\nlog_location             STDOUT\nnode_name                'your_username' # Chef Server kullan\u0131c\u0131 ad\u0131n\u0131z\nclient_key               \"#{current_dir}\/your_username.pem\" # Kullan\u0131c\u0131 anahtar\u0131n\u0131z\u0131n yolu\nchef_server_url          'https:\/\/api.chef.io\/organizations\/your_organization_name' # Chef Server URL'si\ncookbook_path            [\"#{current_dir}\/..\/cookbooks\"]<\/code><\/pre>\n<h4>2. Cookbook'u Chef Server'a Y\u00fckleme<\/h4>\n<p><\/code>chef-repo<code> dizininizin i\u00e7inde oldu\u011funuzdan emin olun ve a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">knife cookbook upload webserver<\/code><\/pre>\n<p>Bu komut, <\/code>webserver<code> cookbook'unu Chef Server'a y\u00fckleyecektir. Chef Server, cookbook'un t\u00fcm tariflerini, niteliklerini, \u015fablonlar\u0131n\u0131 ve dosyalar\u0131n\u0131 depolayacakt\u0131r.<\/p>\n<h4>3. Node'u Chef Server'a Kaydetme (Bootstrap)<\/h4>\n<p>Yeni bir Ubuntu sunucusunu (node) Chef Server taraf\u0131ndan y\u00f6netilecek \u015fekilde haz\u0131rlamak i\u00e7in <\/code>knife bootstrap<code> komutunu kullan\u0131r\u0131z. Bu komut, hedef sunucuya <\/code>chef-client<code>'\u0131 kurar ve onu Chef Server'a kaydeder.<\/p>\n<pre><code class=\"language-bash\">knife bootstrap YOUR_NODE_IP_ADDRESS -N your-ubuntu-node -u your_ssh_user --sudo -i ~\/.ssh\/your_ssh_key.pem<\/code><\/pre>\n<p>*   <\/code>YOUR_NODE_IP_ADDRESS<code>: Y\u00f6netmek istedi\u011finiz Ubuntu sunucusunun IP adresi veya hostname'i.<br \/>\n*   <\/code>-N your-ubuntu-node<code>: Node'a Chef Server'da verilecek isim.<br \/>\n*   <\/code>-u your_ssh_user<code>: Hedef sunucuya SSH ile ba\u011flanmak i\u00e7in kullan\u0131lacak kullan\u0131c\u0131 ad\u0131 (\u00f6rne\u011fin <\/code>ubuntu<code>).<br \/>\n*   <\/code>&#8211;sudo<code>: <\/code>chef-client<code> kurulumu ve \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 i\u00e7in <\/code>sudo<code> yetkisi kullan\u0131r.<br \/>\n*   <\/code>-i ~\/.ssh\/your_ssh_key.pem<code>: SSH ba\u011flant\u0131s\u0131 i\u00e7in kullan\u0131lacak \u00f6zel anahtar\u0131n yolu.<\/p>\n<h4>4. Node'un \u00c7al\u0131\u015ft\u0131rma Listesine Cookbook Ekleme<\/h4>\n<p>Node Chef Server'a kaydedildikten sonra, ona hangi cookbook'lar\u0131n veya tariflerin uygulanaca\u011f\u0131n\u0131 s\u00f6ylememiz gerekir. Bu, node'un \"run list\"ini d\u00fczenleyerek yap\u0131l\u0131r.<\/p>\n<pre><code class=\"language-bash\">knife node run_list add your-ubuntu-node 'recipe[webserver]'<\/code><\/pre>\n<p>Bu komut, <\/code>webserver<code> cookbook'unun <\/code>default<code> tarifini <\/code>your-ubuntu-node<code> adl\u0131 node'un \u00e7al\u0131\u015ft\u0131rma listesine ekler.<\/p>\n<h4>5. Node \u00dczerinde Chef Client \u00c7al\u0131\u015ft\u0131rma<\/h4>\n<p>Son olarak, node \u00fczerinde <\/code>chef-client<code>'\u0131 \u00e7al\u0131\u015ft\u0131rarak Chef Server'dan yap\u0131land\u0131rmay\u0131 \u00e7ekmesini ve uygulamas\u0131n\u0131 sa\u011flar\u0131z:<\/p>\n<p>Node \u00fczerinde SSH ile ba\u011flan\u0131n ve a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">sudo chef-client<\/code><\/pre>\n<p><\/code>chef-client<code>, Chef Server ile ileti\u015fim kuracak, <\/code>webserver<code> tarifini indirecek ve node'unuzu daha \u00f6nce yerel olarak test etti\u011fimiz gibi yap\u0131land\u0131racakt\u0131r. T\u00fcm ad\u0131mlar tamamland\u0131\u011f\u0131nda, node'unuzda Nginx kurulu ve yap\u0131land\u0131r\u0131lm\u0131\u015f olacak, dinamik kar\u015f\u0131lama sayfan\u0131z ve favicon'unuz yay\u0131nda olacakt\u0131r.<\/p>\n<p>Bu ad\u0131mlar, Chef'in da\u011f\u0131t\u0131k mimarisinde cookbook'lar\u0131n nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6stermektedir. Bir kez Chef Server'a y\u00fcklendikten sonra, ayn\u0131 cookbook'u y\u00fczlerce veya binlerce node'a tutarl\u0131 bir \u015fekilde uygulayabilirsiniz.<\/p>\n<h3>En \u0130yi Uygulamalar ve \u0130pu\u00e7lar\u0131<\/h3>\n<p>Chef cookbook'lar\u0131 geli\u015ftirirken ve y\u00f6netirken g\u00f6z \u00f6n\u00fcnde bulundurman\u0131z gereken baz\u0131 en iyi uygulamalar ve ipu\u00e7lar\u0131:<\/p>\n<p>1.  <strong>Idempotency (Tekrar \u00c7al\u0131\u015ft\u0131r\u0131labilirlik):<\/strong> Chef'in temel prensibidir. Tarifleriniz, ka\u00e7 kez \u00e7al\u0131\u015ft\u0131r\u0131l\u0131rsa \u00e7al\u0131\u015ft\u0131r\u0131ls\u0131n, sistemin her zaman ayn\u0131 son duruma ula\u015fmas\u0131n\u0131 sa\u011flamal\u0131d\u0131r. Chef kaynaklar\u0131 varsay\u0131lan olarak idempotenttir, ancak \u00f6zel kaynaklar veya <\/code>execute<code> bloklar\u0131 kullan\u0131rken dikkatli olun.<br \/>\n2.  <strong>Versiyon Kontrol\u00fc (Git):<\/strong> T\u00fcm cookbook'lar\u0131n\u0131z\u0131 ve Chef deponuzu bir versiyon kontrol sisteminde (tercihen Git) y\u00f6netin. Bu, de\u011fi\u015fiklikleri izlemenizi, i\u015fbirli\u011fi yapman\u0131z\u0131 ve hatal\u0131 durumlar\u0131 geri alman\u0131z\u0131 sa\u011flar.<br \/>\n3.  <strong>Cookbook Ba\u011f\u0131ml\u0131l\u0131klar\u0131 (Berkshelf):<\/strong> Cookbook'lar\u0131n\u0131z genellikle di\u011fer topluluk cookbook'lar\u0131na (\u00f6rne\u011fin <\/code>apt<code>, <\/code>nginx<code> cookbook'lar\u0131) ba\u011f\u0131ml\u0131 olacakt\u0131r. Berkshelf, bu ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00f6netmenize ve Chef Server'a y\u00fcklemeden \u00f6nce \u00e7\u00f6zmenize yard\u0131mc\u0131 olur. <\/code>Berksfile<code> dosyas\u0131n\u0131 kullan\u0131n.<br \/>\n4.  <strong>K\u00fc\u00e7\u00fck ve Odakl\u0131 Cookbook'lar:<\/strong> Her cookbook'un tek bir amaca hizmet etmesine \u00f6zen g\u00f6sterin (\u00f6rne\u011fin, <\/code>webserver<code>, <\/code>database<code>, <\/code>monitoring<code>). Bu, cookbook'lar\u0131n\u0131z\u0131 daha y\u00f6netilebilir ve yeniden kullan\u0131labilir hale getirir.<br \/>\n5.  <strong>Niteliklerin Ak\u0131ll\u0131ca Kullan\u0131m\u0131:<\/strong> Cookbook'lar\u0131 daha esnek hale getirmek i\u00e7in nitelikleri kullan\u0131n. Kritik de\u011ferleri hardcode etmekten ka\u00e7\u0131n\u0131n. Niteliklerin \u00f6ncelik s\u0131ras\u0131n\u0131 anlay\u0131n (varsay\u0131lan, override, normal, otomatik).<br \/>\n6.  <strong>\u015eablonlar ve Dosyalar:<\/strong> Dinamik yap\u0131land\u0131rma dosyalar\u0131 i\u00e7in \u015fablonlar\u0131, statik dosyalar i\u00e7in <\/code>files<code> dizinini kullan\u0131n. \u015eablonlarda karma\u015f\u0131k Ruby mant\u0131\u011f\u0131ndan ka\u00e7\u0131n\u0131n; mant\u0131\u011f\u0131 tariflere veya \u00f6zel kaynaklara ta\u015f\u0131y\u0131n.<br \/>\n7.  <strong>Test Odakl\u0131 Geli\u015ftirme (TDD):<\/strong> Test Kitchen ve InSpec kullanarak cookbook'lar\u0131n\u0131z\u0131 d\u00fczenli olarak test edin. Bu, de\u011fi\u015fikliklerin beklenmeyen yan etkileri olmad\u0131\u011f\u0131ndan emin olman\u0131z\u0131 sa\u011flar.<br \/>\n8.  <strong>Topluluk Cookbook'lar\u0131n\u0131 Ke\u015ffedin:<\/strong> Chef Supermarket'te binlerce topluluk taraf\u0131ndan geli\u015ftirilmi\u015f cookbook bulunmaktad\u0131r. \u00c7o\u011fu zaman tekerle\u011fi yeniden icat etmenize gerek kalmaz. Mevcut cookbook'lar\u0131 kullan\u0131n ve kendi ihtiya\u00e7lar\u0131n\u0131za g\u00f6re \u00f6zelle\u015ftirin.<br \/>\n9.  <strong>Data Bags ve Vault:<\/strong> Hassas verileri (parolalar, API anahtarlar\u0131) do\u011frudan cookbook'larda saklamay\u0131n. Bunun yerine Chef Data Bags veya Chef Vault gibi g\u00fcvenli depolama mekanizmalar\u0131n\u0131 kullan\u0131n.<br \/>\n10. <strong>G\u00fcncel Kal\u0131n:<\/strong> Chef s\u00fcrekli geli\u015fen bir platformdur. En son s\u00fcr\u00fcmleri, \u00f6zellikleri ve en iyi uygulamalar\u0131 takip edin.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Bu makalede, Ubuntu \u00fczerinde altyap\u0131y\u0131 y\u00f6netmek i\u00e7in basit Chef cookbook'lar\u0131 olu\u015fturman\u0131n temel ad\u0131mlar\u0131n\u0131 \u00f6\u011frendik. Chef'in IaC prensiplerini nas\u0131l uygulad\u0131\u011f\u0131n\u0131, mimarisini ve temel bile\u015fenlerini anlad\u0131k. Chef Development Kit'i kurarak bir geli\u015ftirme ortam\u0131 haz\u0131rlad\u0131k ve Nginx web sunucusunu kuran, yap\u0131land\u0131ran ve dinamik i\u00e7erik sunan basit bir <\/code>webserver` cookbook&#8217;u olu\u015fturduk. Nitelikler, \u015fablonlar ve dosyalar gibi geli\u015fmi\u015f \u00f6zellikleri kullanarak cookbook&#8217;umuzu daha esnek hale getirdik. Son olarak, Test Kitchen ve InSpec ile cookbook&#8217;lar\u0131m\u0131z\u0131 yerel olarak test etmenin \u00f6nemini vurgulad\u0131k ve Chef Server arac\u0131l\u0131\u011f\u0131yla node&#8217;lara da\u011f\u0131t\u0131m s\u00fcrecine k\u0131saca de\u011findik.<\/p>\n<p>Chef, altyap\u0131 otomasyonu d\u00fcnyas\u0131nda g\u00fc\u00e7l\u00fc ve esnek bir ara\u00e7t\u0131r. Bu makalede ele al\u0131nan temel bilgilerle, kendi altyap\u0131 y\u00f6netimi ihtiya\u00e7lar\u0131n\u0131z i\u00e7in daha karma\u015f\u0131k ve \u00f6zelle\u015ftirilmi\u015f cookbook&#8217;lar geli\u015ftirmeye ba\u015flayabilirsiniz. IaC yakla\u015f\u0131m\u0131n\u0131 benimseyerek, altyap\u0131n\u0131z\u0131 g\u00fcvenilir, tekrarlanabilir ve \u00f6l\u00e7eklenebilir bir \u015fekilde y\u00f6netme yetene\u011fi kazanacaks\u0131n\u0131z. Gelecek ad\u0131mlar\u0131n\u0131z, Chef Supermarket&#8217;i ke\u015ffetmek, daha karma\u015f\u0131k kaynaklar\u0131 ve \u00f6zel kaynaklar\u0131 \u00f6\u011frenmek ve s\u00fcrekli entegrasyon\/s\u00fcrekli da\u011f\u0131t\u0131m (CI\/CD) i\u015flem hatlar\u0131n\u0131za Chef&#8217;i entegre etmek olabilir. Unutmay\u0131n, pratik yapmak ve denemek Chef&#8217;i \u00f6\u011frenmenin en iyi yoludur.<\/p>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#8217;lar\u0131 Olu\u015fturma Rehberi\nGiri\u015f: Altyap\u0131y\u0131 Kod Olarak Y\u00f6netmek (IaC) ve Chef\nG","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":[1468],"tags":[],"class_list":{"0":"post-37859","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-ubuntu","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>Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#039;lar\u0131 Olu\u015fturma Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\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\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#039;lar\u0131 Olu\u015fturma Rehberi\" \/>\n<meta property=\"og:description\" content=\"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#039;lar\u0131 Olu\u015fturma Rehberi Giri\u015f: Altyap\u0131y\u0131 Kod Olarak Y\u00f6netmek (IaC) ve Chef G\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-17T07:41:02+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=\"25 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#8217;lar\u0131 Olu\u015fturma Rehberi\",\"datePublished\":\"2026-01-17T07:41:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/\"},\"wordCount\":2217,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Ubuntu\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/\",\"name\":\"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook'lar\u0131 Olu\u015fturma Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-01-17T07:41:02+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#8217;lar\u0131 Olu\u015fturma Rehberi\"}]},{\"@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":"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook'lar\u0131 Olu\u015fturma Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","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\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/","og_locale":"tr_TR","og_type":"article","og_title":"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook'lar\u0131 Olu\u015fturma Rehberi","og_description":"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook'lar\u0131 Olu\u015fturma Rehberi Giri\u015f: Altyap\u0131y\u0131 Kod Olarak Y\u00f6netmek (IaC) ve Chef G","og_url":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-01-17T07:41:02+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"25 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#8217;lar\u0131 Olu\u015fturma Rehberi","datePublished":"2026-01-17T07:41:02+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/"},"wordCount":2217,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Ubuntu"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/","url":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/","name":"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook'lar\u0131 Olu\u015fturma Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-01-17T07:41:02+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-altyapiyi-yonetmek-icin-basit-chef-cookbooklari-olusturma-rehberi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Ubuntu \u00dczerinde Altyap\u0131y\u0131 Y\u00f6netmek \u0130\u00e7in Basit Chef Cookbook&#8217;lar\u0131 Olu\u015fturma Rehberi"}]},{"@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\/37859","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=37859"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/37859\/revisions"}],"predecessor-version":[{"id":37860,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/37859\/revisions\/37860"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=37859"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=37859"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=37859"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}