Ubuntu Üzerinde Altyapıyı Yönetmek İçin Basit Chef Cookbook’ları Oluşturma Rehberi
Giriş: Altyapıyı Kod Olarak Yönetmek (IaC) ve Chef
Günümüzün hızlı tempolu yazılım geliştirme ve dağıtım dünyasında, altyapıyı manuel olarak yönetmek giderek daha sürdürülemez hale gelmektedir. Sunucu kurulumları, yazılım bağımlılıkları, yapılandırma dosyaları ve hizmetlerin başlatılması gibi görevlerin her seferinde elle yapılması zaman alıcı, hataya açık ve tekrarlanamazdır. İşte tam bu noktada “Altyapıyı Kod Olarak” (Infrastructure as Code – IaC) kavramı devreye girer. IaC, altyapı bileşenlerini ve yapılandırmalarını kod olarak tanımlayarak, versiyon kontrol sistemleri aracılığıyla yönetilmesini, test edilmesini ve otomatikleştirilmesini sağlar. Bu sayede, geliştirme, test ve üretim ortamları arasında tutarlılık sağlanır, dağıtım süreçleri hızlanır ve insan kaynaklı hatalar minimize edilir.
Chef, bu IaC felsefesini benimseyen güçlü bir otomasyon platformudur. Ruby tabanlı bir DSL (Domain Specific Language) kullanarak sunucuların nasıl yapılandırılacağını, yazılımların nasıl kurulacağını ve hizmetlerin nasıl yönetileceğini tanımlamanıza olanak tanır. Chef ile altyapınızı bir kez kod olarak tanımladığınızda, bu tanımı yüzlerce sunucuya tutarlı bir şekilde uygulayabilir, zaman ve emekten tasarruf edebilirsiniz. Chef’in sunduğu tekrarlanabilirlik, ölçeklenebilirlik ve tutarlılık, modern DevOps yaklaşımlarının temelini oluşturur.
Bu makalede, Ubuntu işletim sistemi üzerinde basit Chef cookbook’ları oluşturmayı, bunları yerel olarak test etmeyi ve altyapınızı yönetmek için kullanmayı adım adım öğreneceğiz. Chef’in temel bileşenlerini anlayacak, basit bir web sunucusu kurulumunu otomatikleştirecek ve cookbook’larınızı daha dinamik hale getirmek için nitelikler (attributes) ve şablonlar (templates) gibi gelişmiş özelliklerini keşfedeceğiz.
Chef Temelleri: Mimari ve Bileşenler
Chef’i etkili bir şekilde kullanabilmek için temel mimarisini ve ana bileşenlerini anlamak önemlidir. Chef, genellikle üç ana bileşenden oluşan bir istemci-sunucu modelinde çalışır:
Chef Mimarisi
1. Chef Workstation (İş İstasyonu):
* Geliştiricilerin veya sistem yöneticilerinin Chef cookbook’larını yazdığı, test ettiği ve Chef Server ile etkileşim kurduğu makinedir.
* Chef Development Kit (ChefDK) burada yüklüdür. ChefDK, chef, knife, berkshelf, test-kitchen gibi gerekli tüm araçları içerir.
* Cookbook’lar burada oluşturulur ve Chef Server’a yüklenmeden önce test edilir.
2. Chef Server:
* Tüm cookbook’ları, politikaları, düğüm (node) yapılandırmalarını ve düğümlerin mevcut durumunu depolayan merkezi bir depodur.
* Düğümlerin yapılandırma isteklerini alır ve bunlara uygun cookbook’ları ve tarifleri (recipes) gönderir.
* Açık kaynak Chef Server, ticari Chef Automate veya bulut tabanlı Hosted Chef olarak kullanılabilir.
3. Chef Node (Düğüm):
* Chef Server tarafından yönetilen sunuculardır (fiziksel, sanal veya bulut tabanlı).
* Her düğümde chef-client adı verilen bir ajan (agent) çalışır.
* chef-client, belirli aralıklarla veya manuel olarak çalıştırıldığında Chef Server ile iletişim kurar, kendisine atanan run list’i (çalıştırma listesi) alır ve bu listeye göre kendi yapılandırmasını günceller.
* Ohai adı verilen bir araç, düğüm hakkındaki sistem bilgilerini (işletim sistemi, IP adresi, bellek vb.) toplar ve Chef Server’a gönderir.
Temel Chef Bileşenleri
Chef, altyapıyı tanımlamak için çeşitli bileşenleri kullanır:
1. Resource (Kaynak):
* Chef’in temel yapı taşıdır. Bir kaynağın belirli bir durumda (state) olmasını garanti eden bir soyutlamadır.
* Örnekler: package (bir paketin yüklü olmasını sağlar), service (bir hizmetin çalışıyor olmasını sağlar), file (bir dosyanın belirli bir içeriğe sahip olmasını sağlar), user (bir kullanıcının var olmasını sağlar), directory (bir dizinin var olmasını sağlar).
* Her resource, bir tür (type), bir isim (name) ve bir dizi aksiyon (action) ile niteliklere (properties) sahiptir. Örneğin: package 'nginx' do action :install end
2. Recipe (Tarif):
* Bir veya daha fazla kaynağın (resource) bir araya gelerek belirli bir yapılandırma hedefine ulaşmasını sağlayan Ruby kodudur.
* Cookbook’ların kalbidir. Bir tarif, bir web sunucusunun kurulumu, bir veritabanının yapılandırılması veya bir uygulamanın dağıtımı gibi belirli bir görevi tanımlar.
* recipes/default.rb genellikle bir cookbook’un ana tarifidir.
3. Cookbook:
* İlgili tarifleri, dosyaları, şablonları, nitelikleri ve diğer bileşenleri içeren organize bir dizin yapısıdır.
* Belirli bir görevi veya uygulama grubunu yönetmek için gerekli tüm bilgileri barındırır. Örneğin, bir webserver cookbook’u Nginx veya Apache kurulumu ve yapılandırması için tüm tarifleri içerebilir.
4. Attribute (Nitelik):
* Cookbook’ların davranışını dinamik olarak değiştirmek için kullanılan değişkenlerdir.
* Örneğin, bir web sunucusu cookbook’u için varsayılan HTTP portunu (80) bir nitelik olarak tanımlayabilir ve bu niteliği farklı düğümler için farklı değerlerle geçersiz kılabilirsiniz.
* attributes/default.rb dosyasında tanımlanır.
5. Template (Şablon):
* Dinamik olarak oluşturulması gereken yapılandırma dosyaları için kullanılır.
* ERB (Embedded Ruby) sözdizimini kullanarak, niteliklerden veya diğer kaynaklardan gelen verileri bir dosyaya yerleştirebilirsiniz.
* templates/default/ dizininde bulunur ve genellikle .erb uzantısına sahiptir.
6. File (Dosya):
* Bir düğüme kopyalanması gereken statik dosyalar için kullanılır.
* files/default/ dizininde bulunur.
7. Ohai:
* Chef düğümlerinde çalışan ve sistem hakkında çeşitli bilgiler (işletim sistemi, ağ arayüzleri, CPU, bellek vb.) toplayan bir araçtır.
* Bu bilgiler Chef Server’a gönderilir ve tariflerde koşullu mantık oluşturmak için kullanılabilir (örneğin, “yalnızca Ubuntu sunucularında şunu yap”).
Kurulum ve Ortam Hazırlığı (Ubuntu Workstation Üzerinde)
Chef cookbook’ları geliştirmeye başlamadan önce, Chef Workstation’ınızı kurmanız gerekir. Ubuntu üzerinde bu işlem oldukça basittir.
1. Chef Development Kit (ChefDK) Kurulumu
ChefDK, Chef geliştirme için ihtiyacınız olan tüm araçları (Chef Client, Knife, Test Kitchen, Berkshelf vb.) tek bir pakette sunar.
Öncelikle, Chef’in APT deposunu sisteminize eklememiz gerekiyor:
curl https://packages.chef.io/chef.asc | sudo apt-key add -
echo "deb https://packages.chef.io/repos/apt/current $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/chef.list
sudo apt update
Şimdi ChefDK’yı kurabiliriz:
sudo apt install chefdk
Kurulum tamamlandıktan sonra, chef komutunun çalışıp çalışmadığını kontrol edebilirsiniz:
chef -v
Bu komut, yüklü Chef sürümünü göstermelidir.
2. İlk Chef Deponuzu Oluşturma
Cookbook’larınızı ve diğer Chef yapılandırma dosyalarınızı düzenli tutmak için bir “Chef deposu” (Chef repo) oluşturmak iyi bir uygulamadır. Bu, genellikle bir Git deposu olarak yönetilir.
mkdir ~/chef-repo
cd ~/chef-repo
chef generate app . # Mevcut dizinde bir Chef uygulaması yapısı oluşturur
Bu komut, chef-repo dizini içinde temel bir Chef proje yapısı oluşturacaktır: cookbooks, data_bags, environments, roles, policyfiles gibi dizinler.
3. İlk Cookbook’unuzu Oluşturma
Şimdi webserver adında basit bir cookbook oluşturalım. Bu cookbook, Nginx web sunucusunu kuracak ve yapılandıracaktır.
chef-repo dizininizin içinde olduğunuzdan emin olun ve aşağıdaki komutu çalıştırın:
chef generate cookbook cookbooks/webserver
Bu komut, cookbooks/webserver dizini altında standart bir cookbook yapısı oluşturacaktır:
webserver/
├── Berksfile
├── CHANGELOG.md
├── metadata.rb
├── README.md
├── recipes/
│ └── default.rb
├── test/
│ └── integration/
│ └── default/
│ └── default_test.rb
└── attributes/
└── default.rb
* recipes/default.rb: Bu, cookbook’un ana tarifini içerecek dosyadır.
* metadata.rb: Cookbook hakkında ad, sürüm, açıklama ve bağımlılıklar gibi bilgileri içerir.
* attributes/default.rb: Cookbook için varsayılan nitelikleri tanımlar.
* test/: Test Kitchen ve InSpec testleri için dizin.
Basit Bir Web Sunucusu Cookbook’u Oluşturma (Pratik Örnek)
Şimdi webserver cookbook’umuzu Nginx’i kuracak ve basit bir “Merhaba Dünya” sayfası sunacak şekilde düzenleyelim.
Hedefimiz:
1. Nginx paketini kurmak.
2. Nginx hizmetinin başlatıldığından ve sistem başlangıcında etkinleştirildiğinden emin olmak.
3. Basit bir index.html dosyası oluşturmak.
1. recipes/default.rb Dosyasını Düzenleme
cookbooks/webserver/recipes/default.rb dosyasını açın ve içeriğini aşağıdaki gibi değiştirin:
#
Cookbook:: webserver
Recipe:: default
# Copyright:: 2023, The Authors, All Rights Reserved.
Nginx paketinin yüklü olduğundan emin ol
package 'nginx' do
action :install
end
Nginx hizmetinin çalışır durumda ve sistem başlangıcında etkin olduğundan emin ol
service 'nginx' do
action [:start, :enable]
end
/var/www/html/index.nginx-debian.html dosyasını oluştur ve içeriğini yaz
file '/var/www/html/index.nginx-debian.html' do
content ''
mode '0644'
owner 'www-data'
group 'www-data'
end
Nginx yapılandırma dosyasını değiştirmek isterseniz (isteğe bağlı)
template '/etc/nginx/sites-available/default' do
source 'nginx.conf.erb'
# variables(
# port: node['webserver']['port']
# )
notifies :reload, 'service[nginx]', :immediately
end
Bu tarifte üç ana kaynak (resource) kullanıyoruz:
* package 'nginx': Bu kaynak, nginx paketinin sistemde yüklü olmasını sağlar. action :install ile yükleme işlemini belirtiriz. Chef, paketin zaten yüklü olup olmadığını kontrol eder ve yalnızca gerekliyse yükler (idempotency).
* service 'nginx': Bu kaynak, nginx hizmetinin [:start, :enable] aksiyonlarıyla hem başlatılmasını hem de sistem başlangıcında otomatik olarak başlaması için etkinleştirilmesini sağlar.
* file '/var/www/html/index.nginx-debian.html': Bu kaynak, belirtilen yolda bir dosya oluşturur veya var olanı günceller. content niteliği ile dosyanın içeriğini belirleriz. mode, owner ve group nitelikleri ile dosya izinlerini ve sahipliğini ayarlarız. Nginx’in varsayılan sayfa yolu index.nginx-debian.html olduğu için bu dosyayı hedefliyoruz.
2. Cookbook’u Yerel Olarak Test Etme (Chef Zero Modu)
Cookbook’umuzu Chef Server’a yüklemeden veya gerçek bir düğüme dağıtmadan önce yerel olarak test edebiliriz. Chef’in “zero modu” (-z veya --local-mode) tam da bunun için tasarlanmıştır. Chef Zero, geçici bir Chef Server gibi davranır ve cookbook’ları yerel sisteminizde çalıştırır.
chef-repo dizininizin içinde olduğunuzdan emin olun ve aşağıdaki komutu çalıştırın:
sudo chef-client --local-mode --runlist 'recipe[webserver]'
veya daha kısası:
sudo chef-client -z -o webserver
* sudo: Nginx kurulumu ve dosya yazma işlemleri root yetkisi gerektirdiği için sudo kullanıyoruz.
* -z veya --local-mode: Chef’i zero modunda çalıştırır.
* -o webserver veya --runlist 'recipe[webserver]': webserver cookbook’unun default tarifini çalıştırma listesine ekler. (default tarifini belirtmeye gerek yoktur, çünkü cookbook adı varsayılan olarak default tarifini çağırır.)
Komut çalıştırıldığında, Chef, Nginx’i kuracak, hizmeti başlatacak ve index.nginx-debian.html dosyasını oluşturacaktır. Konsolda, Chef’in her bir kaynağı başarıyla işlediğini gösteren çıktılar göreceksiniz.
3. Doğrulama
Chef çalıştıktan sonra, web sunucusunun başarıyla kurulduğunu doğrulayalım:
1. Nginx hizmetinin durumunu kontrol edin:
systemctl status nginx
Çıktıda active (running) ibaresini görmelisiniz.
2. Web sayfasını kontrol edin:
Web tarayıcınızı açın ve http://localhost adresine gidin.
` mesajını içeren sayfanızı görmelisiniz.
Tebrikler! İlk basit Chef cookbook'unuzu başarıyla oluşturdunuz ve yerel sisteminizde çalıştırdınız.
Cookbook'u Geliştirme: Attribute, Template ve File Kullanımı
Cookbook'larımızı daha esnek ve dinamik hale getirmek için nitelikleri (attributes), şablonları (templates) ve statik dosyaları (files) kullanabiliriz.
1. Attribute Kullanımı: Nginx Portunu Özelleştirme
Şu anda Nginx varsayılan olarak 80. portta çalışıyor. Diyelim ki farklı bir portta çalışmasını istiyoruz veya bu portu bir nitelik olarak yapılandırılabilir hale getirmek istiyoruz.
cookbooks/webserver/attributes/default.rb dosyasını açın ve aşağıdaki içeriği ekleyin:
#
Cookbook:: webserver
Attribute:: default
# Copyright:: 2023, The Authors, All Rights Reserved.
default['webserver']['port'] = 80
default['webserver']['welcome_message'] = 'Chef ile Altyapi Yonetimi Harika!'
Burada webserver cookbook'u için iki nitelik tanımladık: port ve welcome_message. default ön eki, bu niteliklerin varsayılan değerler olduğunu belirtir.
Şimdi bu niteliği recipes/default.rb tarifimizde kullanalım. Nginx'in yapılandırma dosyasını (örneğin /etc/nginx/sites-available/default) değiştirmemiz gerekecek. Bunun için bir şablon kullanacağız.
2. Template Kullanımı: Dinamik Nginx Yapılandırması ve Karşılama Sayfası
Nginx'in varsayılan yapılandırma dosyasını değiştirmek ve index.html içeriğini dinamik hale getirmek için şablonları kullanacağız.
Adım 1: Nginx Yapılandırma Şablonu Oluşturma
cookbooks/webserver/templates/default/ dizini oluşturun (eğer yoksa) ve içine nginx.conf.erb adında bir dosya oluşturun:
mkdir -p cookbooks/webserver/templates/default/
cookbooks/webserver/templates/default/nginx.conf.erb dosyasını açın ve aşağıdaki içeriği ekleyin:
server {
listen <%= node['webserver']['port'] %> default_server;
listen [::]:<%= node['webserver']['port'] %> default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
Bu şablonda, Ruby'nin ERB sözdizimini (<%= ... %>) kullanarak node[‘webserver’][‘port’] niteliğini Nginx listen direktifine yerleştirdik. Chef, bu şablonu işlediğinde, node[‘webserver’][‘port’] ifadesinin yerine attributes/default.rb dosyasında tanımladığımız değeri (varsayılan olarak 80) koyacaktır.
Adım 2: Karşılama Sayfası Şablonu Oluşturma
Aynı dizinde index.html.erb adında bir dosya daha oluşturalım:
cookbooks/webserver/templates/default/index.html.erb
Chef Nginx Web Server
Bu sayfa Chef tarafından otomatik olarak oluşturulmuştur.
Nginx portu: <%= node['webserver']['port'] %>
Sunucu zamanı: <%= Time.now.strftime("%Y-%m-%d %H:%M:%S") %>
Bu şablonda, welcome_message niteliğini ve port niteliğini kullanarak dinamik bir karşılama sayfası oluşturuyoruz. Ayrıca, Ruby'nin Time.now fonksiyonunu kullanarak sunucunun güncel zamanını da ekliyoruz.
Adım 3: Tarifimizi Güncelleme
Şimdi cookbooks/webserver/recipes/default.rb dosyamızı bu şablonları kullanacak şekilde güncelleyelim:
#
Cookbook:: webserver
Recipe:: default
# Copyright:: 2023, The Authors, All Rights Reserved.
Nginx paketinin yüklü olduğundan emin ol
package 'nginx' do
action :install
end
Nginx hizmetinin çalışır durumda ve sistem başlangıcında etkin olduğundan emin ol
service 'nginx' do
action [:start, :enable]
end
Nginx yapılandırma dosyasını şablondan oluştur
template '/etc/nginx/sites-available/default' do
source 'nginx.conf.erb'
mode '0644'
owner 'root'
group 'root'
variables(
port: node['webserver']['port'] # Nitelikleri şablona değişken olarak geçir
)
# Yapılandırma değiştiğinde Nginx hizmetini yeniden yükle
notifies :reload, 'service[nginx]', :immediately
end
Nginx varsayılan siteyi etkinleştir (eğer daha önce yapılmadıysa)
link '/etc/nginx/sites-enabled/default' do
to '/etc/nginx/sites-available/default'
not_if { ::File.exist?('/etc/nginx/sites-enabled/default') }
notifies :reload, 'service[nginx]', :immediately
end
Karşılama sayfasını şablondan oluştur
template '/var/www/html/index.html' do # Artık index.nginx-debian.html yerine index.html kullanıyoruz
source 'index.html.erb'
mode '0644'
owner 'www-data'
group 'www-data'
variables(
welcome_message: node['webserver']['welcome_message'],
port: node['webserver']['port']
)
end
Önceki index.nginx-debian.html dosyasını kaldır (isteğe bağlı ama iyi bir pratik)
file '/var/www/html/index.nginx-debian.html' do
action :delete
only_if { ::File.exist?('/var/www/html/index.nginx-debian.html') }
end
Değişikliklerin Açıklaması:
* template kaynaklarını kullanarak nginx.conf.erb ve index.html.erb şablonlarını ilgili yollara kopyalıyoruz.variables
* bloğu ile nitelikleri şablona değişken olarak iletiyoruz.notifies :reload, ‘service[nginx]’, :immediately
* ifadesi, Nginx yapılandırma dosyası değiştiğinde Nginx hizmetini hemen yeniden yüklemesini sağlar. Bu, Chef'in "notification" mekanizmasıdır ve kaynaklar arasındaki bağımlılıkları yönetmek için çok güçlüdür.sites-available
* Nginx'in dizinindeki yapılandırmayı sites-enabled dizinine bağlayarak etkinleştiriyoruz.file
* Önceki statik kaynağını kaldırdık ve yerine template kullandık. Ayrıca eski index.nginx-debian.html dosyasını siliyoruz.
3. File Kullanımı: Statik Bir Favicon Ekleme
Cookbook'unuza statik bir resim, CSS dosyası veya başka bir ikili dosya eklemek isterseniz files dizinini kullanabilirsiniz.
Adım 1: Favicon Dosyası Ekleme
cookbooks/webserver/files/default/ dizini oluşturun (eğer yoksa) ve içine favicon.ico adında bir dosya yerleştirin. Bu dosyayı internetten bulabilir veya kendiniz oluşturabilirsiniz. Örneğin, basit bir ikon dosyası:
mkdir -p cookbooks/webserver/files/default/
Buraya kendi favicon.ico dosyanızı yerleştirin.
Örneğin, internetten indirdiğiniz bir dosyayı buraya kopyalayabilirsiniz.
cp ~/Downloads/favicon.ico cookbooks/webserver/files/default/
Adım 2: Tarifimizi Güncelleme
cookbooks/webserver/recipes/default.rb dosyamıza favicon.ico dosyasını web sunucusunun kök dizinine kopyalamak için bir cookbook_file kaynağı ekleyelim:
# ... (önceki kodlar) ...
Statik favicon dosyasını kopyala
cookbook_file '/var/www/html/favicon.ico' do
source 'favicon.ico' # files/default/favicon.ico dosyasını işaret eder
mode '0644'
owner 'www-data'
group 'www-data'
end
4. Yerel Olarak Test Etme ve Doğrulama
Tüm bu değişikliklerden sonra, cookbook'umuzu tekrar yerel modda çalıştıralım:
sudo chef-client -z -o webserver
Chef'in çıktısında Nginx yapılandırma dosyasının, index.html dosyasının ve favicon.ico dosyasının güncellendiğini görmelisiniz. Ayrıca Nginx hizmetinin yeniden yüklendiğini de belirtmelidir.
Şimdi tarayıcınızdan http://localhost adresine tekrar gidin:
* Yeni dinamik karşılama mesajını ve Nginx portunu içeren sayfanızı görmelisiniz.
* Tarayıcınızın sekmesinde favicon'un göründüğünden emin olun.
* Eğer portu değiştirmek isterseniz, cookbooks/webserver/attributes/default.rb dosyasındaki default[‘webserver’][‘port’] = 80 satırını default[‘webserver’][‘port’] = 8080 gibi bir değerle değiştirin ve chef-client'ı tekrar çalıştırın. Nginx artık yeni portta hizmet verecektir (eski portta çalışmayacaktır).
Cookbook'ları Test Etme (Test Kitchen ve InSpec ile)
Cookbook'lar karmaşıklaştıkça, değişikliklerin beklenen şekilde çalıştığından emin olmak için test yapmak hayati önem taşır. Chef ekosistemi, cookbook'ları test etmek için güçlü araçlar sunar: Test Kitchen ve InSpec.
* Test Kitchen: Cookbook'ları farklı işletim sistemi ve platform kombinasyonlarında (örneğin, Ubuntu 20.04, CentOS 7) izole bir ortamda (Docker, Vagrant, bulut sağlayıcılar) test etmenizi sağlar.
* InSpec: Altyapınızın güvenlik ve uyumluluk durumunu tanımlamak ve doğrulamak için kullanılan bir denetim ve test çerçevesidir.
1. Test Kitchen Ortamını Hazırlama
Cookbook'unuzu oluşturduğunuzda, chef generate cookbook komutu otomatik olarak bir .kitchen.yml dosyası ve temel InSpec testleri içeren bir test/integration/default/default_test.rb dosyası oluşturur.
.kitchen.yml dosyası, Test Kitchen'ın hangi sürücüyü (driver - örn: dokken for Docker, vagrant for Vagrant), hangi platformları (işletim sistemleri) ve hangi test süitlerini kullanacağını tanımlar.
cookbooks/webserver/.kitchen.yml dosyasını açın. Varsayılan olarak şöyle bir şey görmelisiniz:
---
driver:
name: dokken
transport:
name: dokken
verifier:
name: inspec
platforms:
- name: ubuntu-22.04
# - name: almalinux-8
suites:
- name: default
run_list:
- recipe[webserver::default]
verifier:
inspec_tests:
- test/integration/default
attributes:
Bu yapılandırma, Test Kitchen'ın Docker kullanarak Ubuntu 22.04 üzerinde testleri çalıştırmasını sağlar.
2. InSpec Testleri Yazma
cookbooks/webserver/test/integration/default/default_test.rb dosyasını açın ve içeriğini Nginx kurulumumuzu doğrulayacak şekilde güncelleyin:
# InSpec testleri Ruby tabanlıdır ve altyapınızın beklenen durumda olup olmadığını doğrular.
Nginx paketinin yüklü olup olmadığını kontrol et
describe package('nginx') do
it { should be_installed }
end
Nginx hizmetinin çalışır durumda ve etkin olup olmadığını kontrol et
describe service('nginx') do
it { should be_installed } # Nginx hizmetinin yüklü olduğunu kontrol eder
it { should be_enabled } # Sistem başlangıcında etkin olup olmadığını kontrol eder
it { should be_running } # Şu anda çalışıyor olup olmadığını kontrol eder
end
Nginx yapılandırma dosyasının varlığını ve içeriğini kontrol et
describe file('/etc/nginx/sites-available/default') do
it { should exist }
its('content') { should match /listen #{attribute('port')} default_server;/ } # Nitelikten gelen portu kontrol et
end
Nginx sites-enabled linkinin varlığını kontrol et
describe file('/etc/nginx/sites-enabled/default') do
it { should be_symlink }
it { should be_linked_to '/etc/nginx/sites-available/default' }
end
Karşılama sayfasının varlığını ve içeriğini kontrol et
describe file('/var/www/html/index.html') do
it { should exist }
its('content') { should match /#{attribute('welcome_message')}<\/h1>/ } # Nitelikten gelen mesajı kontrol et
its('content') { should match /Nginx portu: #{attribute('port')}<\/strong>/ }
end
Favicon dosyasının varlığını kontrol et
describe file('/var/www/html/favicon.ico') do
it { should exist }
it { should be_file }
it { should be_owned_by 'www-data' }
end
Nginx'in belirli bir portta dinlediğini kontrol et
describe port(attribute('port')) do
it { should be_listening }
end
Bu InSpec testleri, cookbook'umuzun yaptığı her şeyi doğruluyor: paket kurulumu, hizmet durumu, dosya varlığı ve içeriği, bağlantılar ve hatta ağ portu dinleme durumu. attribute(‘port’) ve attribute(‘welcome_message’) kullanarak testleri cookbook nitelikleriyle senkronize ediyoruz. Bu nitelikler .kitchen.yml dosyasındaki attributes bloğundan veya doğrudan node objesinden alınır.
.kitchen.yml dosyasındaki suites altındaki attributes bloğuna, testler sırasında kullanılacak nitelikleri ekleyelim:
suites:
- name: default
run_list:
- recipe[webserver::default]
verifier:
inspec_tests:
- test/integration/default
attributes:
webserver:
port: 80 # attributes/default.rb dosyasındaki değeriyle eşleşmeli
welcome_message: 'Chef ile Altyapi Yonetimi Harika!' # attributes/default.rb dosyasındaki değeriyle eşleşmeli
3. Testleri Çalıştırma
chef-repo dizininizin içinde olduğunuzdan emin olun ve aşağıdaki komutları çalıştırın:
* Test ortamını oluştur ve cookbook'u uygula (converge):
kitchen converge
Bu komut, Docker container'ını başlatacak, Chef Client'ı yükleyecek ve webserver::default tarifini uygulayacaktır.
* Uygulanan cookbook'u doğrula (verify):
kitchen verify
Bu komut, container üzerinde InSpec testlerini çalıştıracak ve tüm testlerin geçip geçmediğini bildirecektir. Eğer bir test başarısız olursa, nerede hata olduğunu gösteren ayrıntılı bir çıktı alırsınız.
* Tüm adımları tek seferde çalıştır (test):
kitchen test
Bu komut create, converge, verify ve destroy adımlarını sırasıyla çalıştırır.
* Test ortamını yok et (destroy):
kitchen destroy
Testleriniz bittikten sonra, oluşturulan Docker container'ını temizlemek için bu komutu kullanın.
Test Kitchen ve InSpec kullanarak, cookbook'larınızın beklendiği gibi çalıştığından ve altyapınızın tutarlı bir durumda olduğundan emin olabilirsiniz. Bu, geliştirme sürecinde güveni artırır ve üretim ortamına dağıtım riskini azaltır.
Cookbook'u Chef Server'a Yükleme ve Node'lara Uygulama
Şimdiye kadar cookbook'umuzu yerel olarak test ettik. Gerçek dünya senaryolarında, cookbook'ları bir Chef Server'a yükler ve ardından sunucularınızı (node'ları) bu server üzerinden yönetirsiniz.
Bu bölüm, bir Chef Server'ın kurulu olduğunu ve Chef Workstation'ınızın bu server ile iletişim kuracak şekilde yapılandırıldığını varsaymaktadır (genellikle .chef/config.rb ve .chef/YOUR_ORGANIZATION_NAME-validator.pem dosyaları ile). Eğer bir Chef Server'ınız yoksa, Hosted Chef kullanabilir veya yerel bir Chef Server kurabilirsiniz (ancak bu makalenin kapsamı dışındadır).
1. Chef Server Bağlantısını Yapılandırma (Özet)
Chef Server ile iletişim kurmak için Workstation'ınızda .chef dizini ve içinde config.rb dosyası bulunmalıdır. Bu dosya, Chef Server URL'sini, kuruluş adını ve kimlik doğrulama anahtarının yolunu içerir.
# ~/chef-repo/.chef/config.rb (Örnek)
current_dir = File.dirname(__FILE__)
log_level :info
log_location STDOUT
node_name 'your_username' # Chef Server kullanıcı adınız
client_key "#{current_dir}/your_username.pem" # Kullanıcı anahtarınızın yolu
chef_server_url 'https://api.chef.io/organizations/your_organization_name' # Chef Server URL'si
cookbook_path ["#{current_dir}/../cookbooks"]
2. Cookbook'u Chef Server'a Yükleme
chef-repo dizininizin içinde olduğunuzdan emin olun ve aşağıdaki komutu çalıştırın:
knife cookbook upload webserver
Bu komut, webserver cookbook'unu Chef Server'a yükleyecektir. Chef Server, cookbook'un tüm tariflerini, niteliklerini, şablonlarını ve dosyalarını depolayacaktır.
3. Node'u Chef Server'a Kaydetme (Bootstrap)
Yeni bir Ubuntu sunucusunu (node) Chef Server tarafından yönetilecek şekilde hazırlamak için knife bootstrap komutunu kullanırız. Bu komut, hedef sunucuya chef-client'ı kurar ve onu Chef Server'a kaydeder.
knife bootstrap YOUR_NODE_IP_ADDRESS -N your-ubuntu-node -u your_ssh_user --sudo -i ~/.ssh/your_ssh_key.pem
* YOUR_NODE_IP_ADDRESS: Yönetmek istediğiniz Ubuntu sunucusunun IP adresi veya hostname'i.-N your-ubuntu-node
* : Node'a Chef Server'da verilecek isim.-u your_ssh_user
* : Hedef sunucuya SSH ile bağlanmak için kullanılacak kullanıcı adı (örneğin ubuntu).–sudo
* : chef-client kurulumu ve çalıştırılması için sudo yetkisi kullanır.-i ~/.ssh/your_ssh_key.pem
* : SSH bağlantısı için kullanılacak özel anahtarın yolu.
4. Node'un Çalıştırma Listesine Cookbook Ekleme
Node Chef Server'a kaydedildikten sonra, ona hangi cookbook'ların veya tariflerin uygulanacağını söylememiz gerekir. Bu, node'un "run list"ini düzenleyerek yapılır.
knife node run_list add your-ubuntu-node 'recipe[webserver]'
Bu komut, webserver cookbook'unun default tarifini your-ubuntu-node adlı node'un çalıştırma listesine ekler.
5. Node Üzerinde Chef Client Çalıştırma
Son olarak, node üzerinde chef-client'ı çalıştırarak Chef Server'dan yapılandırmayı çekmesini ve uygulamasını sağlarız:
Node üzerinde SSH ile bağlanın ve aşağıdaki komutu çalıştırın:
sudo chef-client
chef-client, Chef Server ile iletişim kuracak, webserver tarifini indirecek ve node'unuzu daha önce yerel olarak test ettiğimiz gibi yapılandıracaktır. Tüm adımlar tamamlandığında, node'unuzda Nginx kurulu ve yapılandırılmış olacak, dinamik karşılama sayfanız ve favicon'unuz yayında olacaktır.
Bu adımlar, Chef'in dağıtık mimarisinde cookbook'ların nasıl kullanıldığını göstermektedir. Bir kez Chef Server'a yüklendikten sonra, aynı cookbook'u yüzlerce veya binlerce node'a tutarlı bir şekilde uygulayabilirsiniz.
En İyi Uygulamalar ve İpuçları
Chef cookbook'ları geliştirirken ve yönetirken göz önünde bulundurmanız gereken bazı en iyi uygulamalar ve ipuçları:
1. Idempotency (Tekrar Çalıştırılabilirlik): Chef'in temel prensibidir. Tarifleriniz, kaç kez çalıştırılırsa çalıştırılsın, sistemin her zaman aynı son duruma ulaşmasını sağlamalıdır. Chef kaynakları varsayılan olarak idempotenttir, ancak özel kaynaklar veya execute blokları kullanırken dikkatli olun.apt
2. Versiyon Kontrolü (Git): Tüm cookbook'larınızı ve Chef deponuzu bir versiyon kontrol sisteminde (tercihen Git) yönetin. Bu, değişiklikleri izlemenizi, işbirliği yapmanızı ve hatalı durumları geri almanızı sağlar.
3. Cookbook Bağımlılıkları (Berkshelf): Cookbook'larınız genellikle diğer topluluk cookbook'larına (örneğin , nginx cookbook'ları) bağımlı olacaktır. Berkshelf, bu bağımlılıkları yönetmenize ve Chef Server'a yüklemeden önce çözmenize yardımcı olur. Berksfile dosyasını kullanın.webserver
4. Küçük ve Odaklı Cookbook'lar: Her cookbook'un tek bir amaca hizmet etmesine özen gösterin (örneğin, , database, monitoring). Bu, cookbook'larınızı daha yönetilebilir ve yeniden kullanılabilir hale getirir.files
5. Niteliklerin Akıllıca Kullanımı: Cookbook'ları daha esnek hale getirmek için nitelikleri kullanın. Kritik değerleri hardcode etmekten kaçının. Niteliklerin öncelik sırasını anlayın (varsayılan, override, normal, otomatik).
6. Şablonlar ve Dosyalar: Dinamik yapılandırma dosyaları için şablonları, statik dosyalar için dizinini kullanın. Şablonlarda karmaşık Ruby mantığından kaçının; mantığı tariflere veya özel kaynaklara taşıyın.
7. Test Odaklı Geliştirme (TDD): Test Kitchen ve InSpec kullanarak cookbook'larınızı düzenli olarak test edin. Bu, değişikliklerin beklenmeyen yan etkileri olmadığından emin olmanızı sağlar.
8. Topluluk Cookbook'larını Keşfedin: Chef Supermarket'te binlerce topluluk tarafından geliştirilmiş cookbook bulunmaktadır. Çoğu zaman tekerleği yeniden icat etmenize gerek kalmaz. Mevcut cookbook'ları kullanın ve kendi ihtiyaçlarınıza göre özelleştirin.
9. Data Bags ve Vault: Hassas verileri (parolalar, API anahtarları) doğrudan cookbook'larda saklamayın. Bunun yerine Chef Data Bags veya Chef Vault gibi güvenli depolama mekanizmalarını kullanın.
10. Güncel Kalın: Chef sürekli gelişen bir platformdur. En son sürümleri, özellikleri ve en iyi uygulamaları takip edin.
Sonuç
Bu makalede, Ubuntu üzerinde altyapıyı yönetmek için basit Chef cookbook'ları oluşturmanın temel adımlarını öğrendik. Chef'in IaC prensiplerini nasıl uyguladığını, mimarisini ve temel bileşenlerini anladık. Chef Development Kit'i kurarak bir geliştirme ortamı hazırladık ve Nginx web sunucusunu kuran, yapılandıran ve dinamik içerik sunan basit bir webserver` cookbook’u oluşturduk. Nitelikler, şablonlar ve dosyalar gibi gelişmiş özellikleri kullanarak cookbook’umuzu daha esnek hale getirdik. Son olarak, Test Kitchen ve InSpec ile cookbook’larımızı yerel olarak test etmenin önemini vurguladık ve Chef Server aracılığıyla node’lara dağıtım sürecine kısaca değindik.
Chef, altyapı otomasyonu dünyasında güçlü ve esnek bir araçtır. Bu makalede ele alınan temel bilgilerle, kendi altyapı yönetimi ihtiyaçlarınız için daha karmaşık ve özelleştirilmiş cookbook’lar geliştirmeye başlayabilirsiniz. IaC yaklaşımını benimseyerek, altyapınızı güvenilir, tekrarlanabilir ve ölçeklenebilir bir şekilde yönetme yeteneği kazanacaksınız. Gelecek adımlarınız, Chef Supermarket’i keşfetmek, daha karmaşık kaynakları ve özel kaynakları öğrenmek ve sürekli entegrasyon/sürekli dağıtım (CI/CD) işlem hatlarınıza Chef’i entegre etmek olabilir. Unutmayın, pratik yapmak ve denemek Chef’i öğrenmenin en iyi yoludur.