---
title: 'Altyapı Sağlama Modelleri'
source: 'https://academia.sh/tr/kurslar/devops-temelleri/altyapi-saglama-modelleri'
course: 'DevOps Kültürü ve Temelleri'
language: tr
updated: '2026-08-17T18:09:05+00:00'
license: 'CC BY-SA 4.0'
---

# Altyapı Sağlama Modelleri

Aynı ortam elle, betikle ve bildirimsel olarak kurulur; iki kurulum arasındaki fark, betiğin ikinci koşumda ve yarıda kaldığında bıraktığı durum ve altı dönem boyunca biriken yapılandırma sapması sayılır. Çalışan bir uzlaştırıcı istenen durumu dosyadan, gerçek durumu diskten okur, farkı kapatır ve ikinci koşumda sıfır iş yapar.

Bir önceki ders on iki ilkeyi denetime çevirdi ve dördünün karar için ikinci bir gözlem — çoğu
zaman ikinci bir ortam — istediğini yazdı. Uygulamanın kendisi artık denetlenebilir durumda:
bağımlılığı bildirilmiş, yapılandırması dışarıda, kapanışı sınanabilir. Altında durduğu makine
ise hâlâ elle kuruluyor ve o makinenin nasıl kurulduğu hiçbir denetimin kapsamında değil.

**Sağlama**, bir ortamı istenen duruma getirme işidir: paketlerin kurulması, ayarların yazılması,
dizinlerin açılması. Üç biçimi vardır — **elle**, **betikle**, **bildirimsel** — ve aralarındaki
ayrım hız değil, **aynı tariften kaç ayrı sonuç doğduğu**dur. Bu ders aynı ortamı üçünde de kurar
ve üç sayıyı ölçer: kurulum adımı, iki kurulum arasındaki fark, ve yapılandırma sapmasının
dönemler boyunca ne kadar büyüdüğü.

Ölçüm yine **bölgesel ölçüm ağı** üzerindedir: su sayacı okumalarını toplayan, doğrulayan ve saha
iş emri açan **kurgu** yazılım. Dosyalar gerçekten diske yazılır, betikler ve uzlaştırıcı
gerçekten koşar.

**DK27.** Ortam yedi kalemle temsil edilir — iki paket sürümü, üç ayar, iki dizin.
**DK28.** Elle kurulumun yönergesi düzyazıdır ve yedi adımın üçü sayı vermez; iki elin yorumu bu
üç adımda ayrılır. **El bir modeldir**, yorumu önceden yazılıdır.
**DK29.** Betik yedi adımı sırayla koşar, hiçbir adım önce durumu okumaz; yarıda kalma noktası bir
ortam değişkeniyle tetiklenir.
**DK30.** Bildirimsel modelde istenen durum bir dosyadır; uzlaştırıcı gerçek durumu diskten okur
ve yalnız farklı kaleme dokunur.
**DK31.** Sapma taramasında altı dönem koşulur ve her dönemde bir elle müdahale yapılır;
müdahaleler önceden yazılıdır, rastgelelik yoktur.

## Üç Model, Aynı Yedi Kalem

```bash
#!/usr/bin/env bash
# Ayni ortamin uc ayri tarifi: bildirim, duzyazi yonerge ve saglama betigi.
set -e

cat > istenen.json <<'SON'
{ "paket/cozumleyici": "3.4.0", "paket/kural-paketi": "9.1.0",
  "ayar/kutuk-duzeyi": "ozet", "ayar/es-zamanli-isci": "8",
  "ayar/toplu-is-baslangic": "02:30", "dizin/veri": null, "dizin/kutuk": null }
SON

cat > tarif-elle.txt <<'SON'
1. paket dizinini ac, cozumleyicinin 3.4.0 surumunu kur
2. kural paketini 9.1.0 surumune sabitle
3. kutuk duzeyini uretime uygun bir degere cek
4. es zamanli isci sayisini makinenin gucune gore ayarla
5. gecelik toplu isi trafigin dusuk oldugu bir saate al
6. veri dizinini ac
7. kutuk dizinini ac
SON

cat > kur.sh <<'SON'
#!/usr/bin/env bash
# Betikle saglama: yedi adim sirayla kosar; hicbir adim once durumu okumaz.
set -e
mkdir -p ortam/paket ortam/ayar ortam/dizin
echo "3.4.0" >> ortam/paket/cozumleyici
echo "9.1.0" >> ortam/paket/kural-paketi
echo "ozet"  >> ortam/ayar/kutuk-duzeyi
[ -z "$KES" ] || exit 3                       # yarida kalma noktasi
echo "8"     >> ortam/ayar/es-zamanli-isci
echo "02:30" >> ortam/ayar/toplu-is-baslangic
mkdir ortam/dizin/veri ortam/dizin/kutuk
SON
```

Üç tarif de aynı yedi kalemi hedefler. Bildirim kalemleri değerleriyle sayar; yönerge üç adımda
sayı vermez ("uygun bir değer", "makinenin gücüne göre", "trafiğin düşük olduğu bir saat"); betik
yedi adımı sırayla koşar. Denetleyici hiçbir şey düzeltmez, yalnız diski istenen durumla
karşılaştırıp sayar.

```js
// denetle.mjs — diskteki ortami istenen durumla karsilastirir ve sayar; hicbir sey duzeltmez.
import { readFileSync, existsSync, statSync } from "node:fs";

const kok = process.argv[2] ?? "ortam";
const istenen = JSON.parse(readFileSync("istenen.json", "utf8"));
const durum = (yol) => {
  const t = `${kok}/${yol}`;
  if (!existsSync(t)) return "eksik";
  const g = statSync(t).isDirectory() ? "" : readFileSync(t, "utf8").trim();
  return g === (istenen[yol] ?? "") ? "uygun" : "sapmis";
};
const s = Object.keys(istenen).map(durum);
const say = (t) => s.filter((x) => x === t).length;
const sapma = say("sapmis") + say("eksik");
console.log(process.argv[3] === "-k" ? sapma                       // -k: yalniz sapma sayisi
  : `  kalem ${s.length}   uygun ${say("uygun")}   sapmis ${say("sapmis")}` +
    `   eksik ${say("eksik")}   sapma ${sapma}`);
```

## Aynı Tarif, Kaç Ayrı Sonuç

```bash
#!/usr/bin/env bash
# Betik modelinin uc senaryosu ve elle kurulumun iki eli.
kos() { printf '%s\n' "$1"; shift; "$@" >/dev/null 2>&1; printf '  betigin cikis kodu %s\n' "$?"; }

rm -rf ortam
kos "1. kosum (bos ortam)"        bash kur.sh
node denetle.mjs
kos "2. kosum (ayni betik yeniden)" bash kur.sh
node denetle.mjs

rm -rf ortam
kos "3. kosum (yarida kesilen)" env KES=1 bash kur.sh
node denetle.mjs
printf '  nerede kaldigini yazan kayit: %s dosya\n' "$(ls ortam/*.durum 2>/dev/null | wc -l | tr -d ' ')"

el() {                                       # $1 dizin, $2..$4 elin yorumladigi uc deger
  rm -rf "$1"; mkdir -p "$1/paket" "$1/ayar" "$1/dizin/veri" "$1/dizin/kutuk"
  printf '3.4.0\n' > "$1/paket/cozumleyici"; printf '9.1.0\n' > "$1/paket/kural-paketi"
  printf '%s\n' "$2" > "$1/ayar/kutuk-duzeyi"; printf '%s\n' "$3" > "$1/ayar/es-zamanli-isci"
  printf '%s\n' "$4" > "$1/ayar/toplu-is-baslangic"
}
el el-1 ozet 8 02:30
el el-2 ayrinti 4 03:00
printf 'elle kurulum: ayni yonergeden iki el\n  iki kurulum arasindaki fark %s kalem\n' \
  "$(diff -rq el-1 el-2 | wc -l | tr -d ' ')"
node denetle.mjs el-1
node denetle.mjs el-2
```

```
1. kosum (bos ortam)
  betigin cikis kodu 0
  kalem 7   uygun 7   sapmis 0   eksik 0   sapma 0
2. kosum (ayni betik yeniden)
  betigin cikis kodu 1
  kalem 7   uygun 2   sapmis 5   eksik 0   sapma 5
3. kosum (yarida kesilen)
  betigin cikis kodu 3
  kalem 7   uygun 3   sapmis 0   eksik 4   sapma 4
  nerede kaldigini yazan kayit: 0 dosya
elle kurulum: ayni yonergeden iki el
  iki kurulum arasindaki fark 3 kalem
  kalem 7   uygun 7   sapmis 0   eksik 0   sapma 0
  kalem 7   uygun 4   sapmis 3   eksik 0   sapma 3
```

Betiğin ilk koşumu yedi kalemin yedisini yerine koyar. Aynı betiğin ikinci koşumu ortamı
**bozar**: beş kalem sapar ve betik yedinci adımda düşer. Nedeni iki karakterdedir — ekleme yapan
`>>` ve `-p` almayan `mkdir`. Betik önce durumu okumadığı için işin daha önce yapılıp
yapılmadığını bilemez; bir işlemin bir kez ile çok kez uygulanmasının aynı sonucu vermesine
**etkisizlik** denir ve bu betik onu taşımaz.

Yarıda kesilen koşum daha pahalıdır: üç kalem yerinde, dört kalem eksik ve **nerede kalındığını
yazan kayıt sıfır**. Ortam ne eski ne yeni durumdadır; betiğin bildirdiği tek şey bir çıkış
kodudur ve o kod hangi adımda durulduğunu söylemez.

Elle kurulumda iki el aynı yönergeyi okudu ve üç kalemde ayrıldı — tam olarak yönergenin sayı
vermediği üç adımda. Buradaki fark bir dikkatsizlik değil, **tarifin yazılmamış kısmıdır**: tarif
ile ortam arasındaki boşluğu insan doldurur ve doldurduğu değer hiçbir yere yazılmaz. Ölçü tek
satıra iner: elle kurulumda aynı tarif iki ayrı sonuç doğurdu, betikle sağlamada ikinci koşum
üçüncü bir sonuç doğurdu — üstelik ilkinden de bozuk olanı.

## Sapmanın Sayılabilir Olması

```js
// uzlastir.mjs — istenen durumu dosyadan, gercek durumu diskten okur; farki yazar ve kapatir.
import { readFileSync, writeFileSync, mkdirSync, existsSync, statSync } from "node:fs";

const istenen = JSON.parse(readFileSync("istenen.json", "utf8"));
const gercek = (yol) => {
  const t = `ortam/${yol}`;
  if (!existsSync(t)) return null;
  return statSync(t).isDirectory() ? "" : readFileSync(t, "utf8").trim();
};

const fark = Object.entries(istenen).map(([yol, d]) => ({ yol, d: d ?? "", g: gercek(yol) }))
  .filter((f) => f.g !== f.d)
  .map((f) => ({ ...f, tur: f.g === null ? "eksik" : "sapmis" }));

for (const f of fark) {                        // uzlastirma: yalniz farkli olan kaleme dokunulur
  const t = `ortam/${f.yol}`;
  if (istenen[f.yol] === null) mkdirSync(t, { recursive: true });
  else {
    mkdirSync(t.slice(0, t.lastIndexOf("/")), { recursive: true });
    writeFileSync(t, istenen[f.yol] + "\n");
  }
}
console.log(`  kalem ${Object.keys(istenen).length}   fark ${fark.length}` +
  `   (eksik ${fark.filter((f) => f.tur === "eksik").length},` +
  ` sapmis ${fark.filter((f) => f.tur === "sapmis").length})   yapilan is ${fark.length}`);
for (const f of fark) console.log(`    ${f.tur.padEnd(6)} ${f.yol.padEnd(24)}` +
  (istenen[f.yol] === null ? " (dizin acilir)" : ` "${f.g ?? ""}" -> "${f.d}"`));
```

```bash
#!/usr/bin/env bash
# Uzlastirici: bos ortam, ikinci kosum (etkisizlik), elle mudahale sonrasi.
rm -rf ortam
echo "1. kosum (bos ortam)";        node uzlastir.mjs
echo "2. kosum (hemen ardindan)";   node uzlastir.mjs
echo "elle mudahale: isci sayisi 16 yapildi, kutuk dizini silindi"
echo 16 > ortam/ayar/es-zamanli-isci; rm -rf ortam/dizin/kutuk
echo "3. kosum (mudahaleden sonra)"; node uzlastir.mjs

mudahale() { case $1 in
  1) echo 16 > ortam/ayar/es-zamanli-isci ;;   2) echo ayrinti > ortam/ayar/kutuk-duzeyi ;;
  3) rm -rf ortam/dizin/kutuk ;;               4) echo 3.5.0 > ortam/paket/cozumleyici ;;
  5) echo 03:15 > ortam/ayar/toplu-is-baslangic ;; 6) echo 9.2.0 > ortam/paket/kural-paketi ;;
esac; }

echo ""
echo "alti donem, her donemde bir elle mudahale (sapma birikimi)"
for uzlastirma in yok var; do
  rm -rf ortam; node uzlastir.mjs > /dev/null
  printf '  uzlastirma %s :' "$uzlastirma"
  for d in 1 2 3 4 5 6; do
    mudahale "$d"
    [ "$uzlastirma" = var ] && node uzlastir.mjs > /dev/null
    printf ' %s' "$(node denetle.mjs ortam -k)"
  done
  printf '\n'
done

echo ""
printf 'tarif buyuklugu (satir): yonerge %s, betik %s, bildirim %s, uzlastirici %s\n' \
  "$(wc -l < tarif-elle.txt)" "$(wc -l < kur.sh)" "$(wc -l < istenen.json)" \
  "$(wc -l < uzlastir.mjs)" | tr -s ' '
```

```
1. kosum (bos ortam)
  kalem 7   fark 7   (eksik 7, sapmis 0)   yapilan is 7
    eksik  paket/cozumleyici        "" -> "3.4.0"
    eksik  paket/kural-paketi       "" -> "9.1.0"
    eksik  ayar/kutuk-duzeyi        "" -> "ozet"
    eksik  ayar/es-zamanli-isci     "" -> "8"
    eksik  ayar/toplu-is-baslangic  "" -> "02:30"
    eksik  dizin/veri               (dizin acilir)
    eksik  dizin/kutuk              (dizin acilir)
2. kosum (hemen ardindan)
  kalem 7   fark 0   (eksik 0, sapmis 0)   yapilan is 0
elle mudahale: isci sayisi 16 yapildi, kutuk dizini silindi
3. kosum (mudahaleden sonra)
  kalem 7   fark 2   (eksik 1, sapmis 1)   yapilan is 2
    sapmis ayar/es-zamanli-isci     "16" -> "8"
    eksik  dizin/kutuk              (dizin acilir)

alti donem, her donemde bir elle mudahale (sapma birikimi)
  uzlastirma yok : 1 2 3 4 5 6
  uzlastirma var : 0 0 0 0 0 0

tarif buyuklugu (satir): yonerge 7, betik 11, bildirim 3, uzlastirici 27
```

Uzlaştırıcı üç iş yapar: istenen durumu dosyadan okur, gerçek durumu diskten okur, yalnız farklı
kaleme dokunur. İlk koşum yedi kalemi eksik bulup yedi iş yapar; ikinci koşum **sıfır iş** yapar.
Betiğin taşımadığı etkisizlik burada ölçülmüş hâldedir ve nedeni tek bir sıra değişikliğidir —
önce okumak, sonra yazmak.

Ayırt edici yan üçüncü koşumdadır. Elle müdahale iki kalemi bozdu; uzlaştırıcı ikisini de adıyla,
eski ve yeni değeriyle yazıp kapattı. **Sapma burada bir sayıdır:** `fark 2`. Öteki iki modelde
sapmayı sayacak yer yoktu, çünkü istenen durum okunabilir bir nesne değildi — biri insanın
yorumunda, öteki bir komut dizisinde duruyordu. Komut dizisi **ne yapılacağını** söyler, **ne
olması gerektiğini** söylemez; sapmanın sayılabilirliği bu iki cümle arasındaki farktır.

Altı dönemlik tarama bunu iki satıra indirir: uzlaştırma koşmadığında müdahaleler birikir (1, 2,
3, 4, 5, 6), koştuğunda dizi sıfırda kalır. Sapma yok olmuyor, her dönemde doğup kapanıyor.
Birikmeyen şey sapmanın kendisi değil, **bilinmeyen sapmadır**.

## Üç Modelin Bedeli

| Ölçü | Elle | Betikle | Bildirimsel |
|---|---|---|---|
| tarif büyüklüğü (satır) | 7 | 11 | 3 artı 27 (bir kez yazılır) |
| ilk kurulumda yerine gelen kalem | 7 ve 4 (iki el) | 7 | 7 |
| aynı tariften ayrı sonuç | 2 | 2 | 1 |
| tarif ikinci kez koşarsa | ölçülemez | 5 kalem sapar, çıkış 1 | 0 iş |
| yarıda kalırsa geriye kalan | kayıtsız | 3 kalem, 0 kayıt | fark yeniden hesaplanır |
| 6 dönemde biriken sapma | 1'den 6'ya | 1'den 6'ya | her dönem 0 |
| sapmayı yakalama | yok | yok | bildirimdeki 7 kalem |

Yazım maliyeti bildirimsel modelde en düşük görünür — üç satır — ama sayı yanıltıcıdır:
uzlaştırıcı yirmi yedi satırdır ve farkı yapan şey onun **bir kez** yazılıp her ortam için yeniden
kullanılmasıdır. Betik on bir satırdır ve her yeni kalemle büyür; yönerge yedi satırdır ve
büyüdükçe belirsizliği de büyür, çünkü düzyazının her cümlesi bir yorum noktasıdır.

İlk kurulum süresi üç modelde de aynı mertebededir; ayrım orada değil, ikinci koşumda ve
müdahaleden sonra çıkar. Sağlama tartışmasının en sık kaçırdığı yer budur: yalnız ilk kurulumla
karşılaştırıldığında betik yeterli görünür, çünkü orada bildirimsel modelle **aynı sonucu** verir.

Bildirimsel modelin sınırı da sayılabilir. Uzlaştırıcı yalnız bildirimde yazan yedi kalemi görür;
ortama sekizinci bir dosya elle eklendiğinde hiçbir koşumda fark olarak çıkmaz. **Sapmayı
sayılabilir kılan şey bildirimin kapsamıdır** ve kapsam dışındaki fark hiçbir yerde yazılı olmayan
bir yerde birikir: bir elin yorumunda, yarıda kalmış bir koşumun kısmi durumunda. Bu konunun ilk
dersinde yalnız koşumda görünen altı farkın kaynağı burasıdır.

## Özet

- Elle kurulumda iki el aynı yönergeden 3 kalemde ayrıldı; ayrıldıkları adımlar yönergenin sayı
  vermediği üç adımdı.
- Betiğin ilk koşumu 7 kalemi yerine koydu; ikincisi 5 kalemi bozup düştü, yarıda kesileni 3 kalem
  bırakıp 4'ünü eksik ve nerede kalındığını yazan 0 kayıt bıraktı.
- Uzlaştırıcı ilk koşumda 7, ikinci koşumda 0 iş yaptı; elle müdahaleden sonra 2 sapmayı adıyla
  yazıp kapattı.
- Altı dönemde uzlaştırma yokken sapma 1'den 6'ya birikti, varken 0'da kaldı; birikmeyen şey sapma
  değil, bilinmeyen sapmadır.
- Bildirimsel modelin sınırı bildirimin kapsamıdır: kapsam dışındaki her şey elle kurulumdaki
  durumuna geri düşer.

## Kurs Kapanışı

| Ders | Ölçülen fark ya da ölçüt | Sayı | Farkın saklandığı yer |
|---|---|---|---|
| DevOps Nedir | sahibine ulaşmayan olgu, ulaşma adımı | 22 olgunun 4'ü; 7,0 → 1,6 adım | gözlem alanının bölünmesi |
| Duvar Üzerinden Atma | sınırda düşen bağlam kalemi | 29 kalemin 21'i yazısız, 14'ü düşüyor | yazılmamış bağlam |
| Değer Akışı | beklemenin tek adımda yığılması | 2237 adımın 1485'i; katma değer %38,5 | beklemenin dağılımı |
| Teslimat Ölçütleri | parti 8'den 2'ye inince oynayan ölçüt | dağıtım 3,2 → 13,5; hata 12'de sabit | ölçütün paydası |
| Site Güvenilirliği Mühendisliği | hata bütçesi ve tükenmesi | 43,2 dakika; ağır olay %208; 8/12 dönem | hedef ile kesinti dağılımı arası |
| Geri Bildirim Döngüleri | erken döngüye düşmeyen hata | 120 hatanın 32'si, gecikmenin %95'i | döngü kapsamı |
| Ortamlar | ortam denkliği, boyut başına fark | 18 fark; 12 künyede, 6 koşumda | künyede yazmayan boyut |
| Yapı Çıktısı ve Değişmezlik | yeniden üretilebilirliği bozan kaynak | 4 kaynak, 3'ü tek makinede görünmez | çıktıya gömülü değer |
| Yapı Çıktısı Depoları | etiketin taşıdığı ayrı çıktı | 11 adla dağıtım, 7'sinde başka çıktı | dağıtım anındaki ad çözümü |
| Yapılandırma ve Sır Ayrımı | değişen anahtar, sızma yolu | 14 anahtarın 6'sı; 7 sızıntıdan 5'i | kaynağa gömülü varsayılan |
| On İki Etmen Uygulama | denetime çevrilen ilke, yakalanan kusur | 12 ilkenin 8'i; 8 kusurdan 6'sı | kuralın kapsamı ile ilkenin konusu arası |
| Altyapı Sağlama Modelleri | aynı tariften doğan ayrı sonuç | elle 3, betik 5, bildirimsel 0; sapma 6 → 0 | tarifin yazılmamış kısmı |

On iki satırın hepsi tek bir kuralın örneğidir: **aynı yazılım iki ortamda başka davranıyorsa fark
bir yerdedir, ve adı konmadıkça ölçülmez.** Tablodaki hiçbir sayı yazılımın kendisinden gelmiyor;
hepsi farkın saklandığı yerden geliyor. Bir kalemin yazılı olup olmadığı, bir adın dağıtım anında
neye çözüldüğü, bir yönergenin hangi adımda sayı vermediği — bunların hiçbiri kodun içinde
değildir ve hiçbiri kendiliğinden görünmez.

Son sütun okunduğunda bir yığılma görünür: farkın saklandığı yerlerin çoğu **ortamın kendisiydi**
— kurulu paketler, kütüphane sürümleri, dosya yolları, saat dilimi. Künyeyi genişletmek,
yapılandırmayı dışarı almak ve sağlamayı bildirimsel yapmak bu farkı ölçülebilir kıldı, ama farkı
**ortamdan çıkarmadı**; her seferinde yapılan, farkı sayılabilir bir yere taşımak oldu.

Buradan bir soru kalır ve **M22/K02 Konteynerler** onu üstlenir: bu farkı yapı çıktısının içine
alıp ortamdan tümüyle çıkarmak mümkün mü? Kurulu paketler, sürümler ve dosya yolları çıktının
parçası olursa ortamın yapabileceği tek şey o çıktıyı çalıştırmak olur ve sağlanacak bir şey
kalmaz. Mümkünse bedeli nedir — çıktı ne kadar büyür, yeniden üretilebilirlik ne olur, ortamdan
çıkarılamayan ne kalır?
