---
title: 'Kod Olarak Altyapı Nedir'
source: 'https://academia.sh/tr/kurslar/kod-olarak-altyapi/kod-olarak-altyapi-nedir'
course: 'Kod Olarak Altyapı'
language: tr
updated: '2026-08-17T18:09:07+00:00'
license: 'CC BY-SA 4.0'
---

# Kod Olarak Altyapı Nedir

Aynı hazırlık ortamı iki kez kurulur — bir düzyazı talepten elle, bir kayıttan — ve iki kurulum kalem kalem karşılaştırılır. Bir çeyreklik değişikliklerde kim, ne zaman ve ne değiştirdi sorusunun kaç kez yanıtlandığı, kaydın kapsamadığı kalem sayısı ve kayda bağlamanın satır ve ek adım olarak bedeli sayılır.

Bir önceki kurs uygulamanın üretime çıkış yolunu depoya bağladı: dal birleşince hat koşuyor,
kapılar geçiliyor, dağıtım kendiliğinden ilerliyor. Uygulamanın yolu baştan sona yazılı. Altında
durduğu makineler, kuyruk, veri deposu ve ağ ise başka bir yolla kuruluyor — bir talep açılıyor,
biri o talebi okuyup ortamı kuruyor, ve kurulumun sonucu yalnız ortamın kendisinde duruyor.

**Kod olarak altyapı**, altyapının okunabilir bir **kayda** bağlanmasıdır: ortamın ne olması
gerektiği bir dosyada yazılıdır, ortam o dosyadan kurulur. Bu kursun ölçü birimi kayıttır ve her
ders üç şeyi sayar — kaydın söylediği ile gerçeğin farkı, kaydın kapsamı, ve kaydın bedeli.
Bu ders ilkini kurar: aynı ortam iki kez kurulur, bir düzyazı talepten elle ve bir kayıttan, sonra
**kalem kalem** karşılaştırılır. Ardından bir çeyreklik değişiklikte "kim, ne zaman, ne değiştirdi"
sorusunun kaç kez yanıtlandığı, kaydın kapsamadığı kalem sayısı ve kayda bağlamanın satır ve adım
olarak bedeli ölçülür.

Ölçüm **bölgesel ölçüm ağı** üzerindedir: su sayacı okumalarını toplayan, doğrulayan, faturaya
çeviren ve saha iş emri açan **kurgu** yazılım. Üç ortamı vardır; burada yalnız hazırlık ortamı
kurulur. Altyapı gerçekten sağlanmaz — kaynaklar ve kurulumlar `node` ile modellenir; modelin
girdisi olan kayıt ve talep dosyaları gerçekten diske yazılır.

**AT1.** Hazırlık ortamı altı kaynakla temsil edilir — bir ağ, iki makine grubu, bir kuyruk, bir
veri deposu, bir nesne deposu. Kalem bir kaynağın bir niteliğidir; kayıtta yirmi kalem yazılıdır.
**AT2.** Kurulum talebi düzyazıdır ve on bir maddenin yedisi sayı vermez. **El bir modeldir**,
yorumu önceden yazılıdır; rastgelelik yoktur.
**AT3.** Sağlayıcı varsayılanı beş kalemdir: kayıtta yazmayan, ortamda her hâlükârda oluşan
ayarlar. İki kurulumda da aynı doğar.
**AT4.** Bir çeyrekte on dört değişiklik olur; her değişiklik üç soru sorar — kim, ne zaman, ne
değiştirdi. Her değişikliğin yolu önceden yazılıdır.
**AT5.** Kayıt üzerinden geçen değişiklik üç soruyu da yanıtlar; bir iş kaydına düşen değişiklik
ikisini yanıtlar (ne değiştiğini yazmaz); izsiz değişiklik hiçbirini.
**AT6.** Kayıt yolunun değişiklik başına üç ek adımı vardır: kaydı yaz, gözden geçirt, planı oku.

## Aynı Ortam, İki Tarif

```bash
#!/usr/bin/env bash
# Ayni ortamin iki tarifi: kayit (yapilandirma dili) ve duzyazi kurulum talebi.
set -e

cat > kayit.alt <<'SON'
# Yapilandirma dilimizin bicimi: kaynak <tur> "<ad>" { <anahtar> = <deger> }
# Deger sayi, "dize" ya da dogru/yanlis olur; # ile baslayan satir yorumdur.
kaynak ag "olcum-agi" { blok = "10.40.0.0/16"  ozel = dogru  bolge = "kuzey" }
kaynak makine "toplayici" { sayi = 3  boyut = "orta"  disk_gb = 40  imaj = "taban-7" }
kaynak makine "dogrulayici" { sayi = 2  boyut = "kucuk"  disk_gb = 20  imaj = "taban-7" }
kaynak kuyruk "okuma-kuyrugu" { saklama_saat = 72  bolum = 6  olu_mektup = dogru }
kaynak veri_deposu "olcum-deposu" { boyut_gb = 200  yedek_gun = 14  surum = "5.2" }
kaynak nesne_deposu "arsiv" { sinif = "seyrek"  surumleme = dogru  yasam_gun = 365 }
SON

cat > talep.txt <<'SON'
hazirlik ortami kurulum talebi
1. olcum agini ozel olarak ac, adres blogu 10.40.0.0/16, kuzey bolgesi
2. toplayici makinelerden yeterli sayida ac, boyut orta, imaj taban-7
3. toplayici diski olcum hacmine gore ver
4. dogrulayici makinelerden iki tane, boyut kucuk, disk 20 GB, imaj taban-7
5. okuma kuyrugunu ac, saklama suresi uretime yakin olsun, olu mektup acik
6. kuyruk bolum sayisini isci sayisina gore ayarla
7. olcum deposunu 200 GB ac, surum 5.2
8. deponun yedek penceresini kurumsal olcute gore ayarla
9. arsiv icin nesne deposu ac, surumleme acik
10. arsiv saklama sinifini maliyete gore sec
11. arsiv yasam dongusu gunu icin makul bir deger yaz
SON
```

Yapılandırma dili burada kendi küçük biçimimizle tanımlanır: bir `kaynak` satırı bir türü, bir adı
ve süslü parantez içinde anahtar-değer çiftlerini taşır. Altı satır yirmi kalemi sayar ve her kalem
tek bir değere bağlıdır — okuyan iki kişi aynı şeyi anlar. Talep aynı ortamı hedefler ama yedi
maddesi sayı yerine ölçüt verir: "yeterli sayıda", "ölçüm hacmine göre", "üretime yakın", "kurumsal
ölçüte göre", "maliyete göre", "makul bir değer". Bu yedi nokta talebin **yazılmamış** kısmıdır ve
onu kuran kişi doldurur.

```js
// kur.mjs — kaydi ayristirir ve ayni ortami iki yoldan kurar: kayittan ve elle. Ikisi de modeldir.
import { readFileSync } from "node:fs";

const BLOK = /^kaynak\s+(\w+)\s+"([\w-]+)"\s*\{(.*)\}$/;      // dilin tek satirlik bicimi
export const kaydiOku = (metin) => {
  const k = new Map();
  for (const satir of metin.split("\n")) {
    const m = BLOK.exec(satir.trim());                        // yorum ve bos satir atlanir
    if (m) for (const x of m[3].matchAll(/(\w+)\s*=\s*("[^"]*"|[\w./-]+)/g))
      k.set(`${m[1]}.${m[2]}.${x[1]}`, x[2].replaceAll('"', ""));
  }
  return k;
};
export const kayit = kaydiOku(readFileSync("kayit.alt", "utf8"));

// Saglayici varsayilani: kayitta yazmayan, ortamda her halukarda olusan kalemler.
const varsayilan = new Map([["ag.olcum-agi.cikis_yolu", "acik"],
  ["makine.toplayici.erisim_kurali", "yonetim-portu-acik"],
  ["kuyruk.okuma-kuyrugu.sifreleme", "saglayici-anahtari"],
  ["veri_deposu.olcum-deposu.bakim_penceresi", "pazar-03:00"],
  ["nesne_deposu.arsiv.erisim_kurali", "hesap-ici"]]);

// Elin onceden yazili yorumu: talebin sayi vermedigi yedi nokta (2, 3, 5, 6, 8, 10, 11).
const elinYorumu = new Map([["makine.toplayici.sayi", "2"], ["makine.toplayici.disk_gb", "40"],
  ["kuyruk.okuma-kuyrugu.saklama_saat", "24"], ["kuyruk.okuma-kuyrugu.bolum", "6"],
  ["veri_deposu.olcum-deposu.yedek_gun", "7"], ["nesne_deposu.arsiv.sinif", "sik"],
  ["nesne_deposu.arsiv.yasam_gun", "90"]]);
const elinAtladigi = ["nesne_deposu.arsiv.surumleme"];        // talepte yazili, uygulamada atlandi
const elinEkledigi = new Map([["ag.olcum-agi.erisim_kurali", "ofis-blogu"],
  ["makine.toplayici.ek_disk", "bagli"], ["makine.dogrulayici.ad_kaydi", "dogrulayici.ic"]]);

export const kayittanKur = () => new Map([...kayit, ...varsayilan]);
export const elleKur = () => {
  const o = new Map([...kayit, ...elinYorumu, ...varsayilan, ...elinEkledigi]);
  for (const a of elinAtladigi) o.delete(a);
  return o;
};
export const yorumNoktasi = elinYorumu.size, kayitDisi = varsayilan.size;
```

## Kalem Kalem Fark

```js
// fark.mjs — iki kurulumu kalem kalem karsilastirir; hicbir sey duzeltmez.
import { kayit, kayittanKur, elleKur, yorumNoktasi, kayitDisi } from "./kur.mjs";

const a = kayittanKur(), b = elleKur();
const tum = [...new Set([...a.keys(), ...b.keys()])].sort();
const fark = tum.filter((k) => a.get(k) !== b.get(k)).map((k) => ({ k,
  tur: !b.has(k) ? "eksik" : !a.has(k) ? "fazla" : "ayrik" }));
const say = (t) => fark.filter((f) => f.tur === t).length;

console.log(`kalem  kayittan ${a.size}   elle ${b.size}   birlesim ${tum.length}`);
console.log(`fark ${fark.length} kalem   (ayrik ${say("ayrik")}, eksik ${say("eksik")},` +
  ` fazla ${say("fazla")})`);
for (const f of fark)
  console.log(`  ${f.tur.padEnd(6)} ${f.k.padEnd(38)} ${(a.get(f.k) ?? "-").padEnd(20)}` +
    ` ${b.get(f.k) ?? "-"}`);
console.log(`kayittaki kalem ${kayit.size}   talebin sayi vermedigi nokta ${yorumNoktasi}` +
  `   bu noktalarin ayrildigi ${fark.filter((f) => f.tur === "ayrik").length}`);
console.log(`kaydin kapsamadigi kalem ${kayitDisi}   iki kurulumda da ayni,` +
  ` hicbirinde yazili degil`);
```

```
kalem  kayittan 25   elle 27   birlesim 28
fark 9 kalem   (ayrik 5, eksik 1, fazla 3)
  fazla  ag.olcum-agi.erisim_kurali             -                    ofis-blogu
  ayrik  kuyruk.okuma-kuyrugu.saklama_saat      72                   24
  fazla  makine.dogrulayici.ad_kaydi            -                    dogrulayici.ic
  fazla  makine.toplayici.ek_disk               -                    bagli
  ayrik  makine.toplayici.sayi                  3                    2
  ayrik  nesne_deposu.arsiv.sinif               seyrek               sik
  eksik  nesne_deposu.arsiv.surumleme           dogru                -
  ayrik  nesne_deposu.arsiv.yasam_gun           365                  90
  ayrik  veri_deposu.olcum-deposu.yedek_gun     14                   7
kayittaki kalem 20   talebin sayi vermedigi nokta 7   bu noktalarin ayrildigi 5
kaydin kapsamadigi kalem 5   iki kurulumda da ayni, hicbirinde yazili degil
```

Aynı ortamın iki kurulumu dokuz kalemde ayrıldı ve fark üç ayrı türden geliyor. **Ayrık** beş
kalem, talebin sayı vermediği yedi noktanın beşidir: kalan ikisi elin yorumu kayıtla aynı değere
düştüğü için görünmez. Bu ikisi bir kazanç değil, bir tesadüftür — yorum noktası hâlâ yedidir,
yalnız beşi bu koşumda ayrıldı. **Eksik** bir kalem talepte açıkça yazılıydı ve uygulanmadı;
düzyazı bir listede atlanan madde hiçbir yerde iz bırakmaz. **Fazla** üç kalem ise talepte hiç
geçmiyor: bir erişim kuralı, bir ek disk ve bir ad kaydı. Bunlar ortamı kuran kişinin rutininden
geliyor ve hiçbir tarifte yazılı değil — kurulum bittiğinde varlar, ama neden var oldukları
yalnız bir kişinin belleğinde.

Farkın yönü de anlamlıdır. Ayrık beş kalemin dördünde elin değeri kayıttakinden **küçüktür** — iki
toplayıcı yerine üç, yetmiş iki saat yerine yirmi dört, on dört gün yerine yedi, üç yüz altmış beş
gün yerine doksan. Ölçüt vermeyen bir talep okunduğunda seçilen değer, o anda görünen yükü karşılar;
kaydın taşıdığı değer ise bir kez kararlaştırılmış olanı taşır. İki kurulum arasındaki fark bu
yüzden bir hata listesi değil, **iki ayrı karar anının** listesidir.

Son satır bu dersin ölçü ekseninin ikinci yarısıdır. Kaydın kapsamadığı beş kalem **her iki
kurulumda da** aynıdır, çünkü ikisini de sağlayıcı doğuruyor: çıkış yolu, yönetim portu kuralı,
şifreleme anahtarı, bakım penceresi, hesap içi erişim kuralı. Kayıt bunlar hakkında bir şey
söylemediği için bir karşılaştırma bunları hiçbir zaman fark olarak göstermez. Kaydı yazmak farkı
sıfırlamaz; farkı **kaydın kapsamı kadar** görünür kılar.

## Kim, Ne Zaman, Ne Değiştirdi

```js
// izle.mjs — bir donemdeki degisiklikler iki ortamda ne kadar izlenebiliyor. Model.
import { kayit } from "./kur.mjs";

// Bir ceyrekteki on dort degisiklik; onceden yazilidir, rastgelelik yoktur.
const D = [["makine.toplayici.sayi", "kayit"], ["makine.toplayici.boyut", "kayit"],
  ["kuyruk.okuma-kuyrugu.bolum", "kayit"], ["veri_deposu.olcum-deposu.boyut_gb", "kayit"],
  ["makine.toplayici.erisim_kurali", "elle"], ["nesne_deposu.arsiv.yasam_gun", "kayit"],
  ["ag.olcum-agi.blok", "kayit"], ["makine.dogrulayici.sayi", "kayit"],
  ["kuyruk.okuma-kuyrugu.saklama_saat", "elle"], ["veri_deposu.olcum-deposu.yedek_gun", "kayit"],
  ["makine.dogrulayici.imaj", "kayit"], ["nesne_deposu.arsiv.sinif", "kayit"],
  ["ag.olcum-agi.cikis_yolu", "elle"], ["makine.toplayici.disk_gb", "kayit"]];
const isKaydiOlan = [0, 3, 7, 10];                    // elle kurulan ortamda bilet acilan dortu

// Kayit uzerinden gecen degisiklik uc soruyu da yanitlar; is kaydi ikisini (ne degistigini yazmaz).
const yanit = { kayit: 3, bilet: 2, izsiz: 0 };
const A = D.map(([, y]) => (y === "kayit" ? "kayit" : "izsiz"));
const B = D.map((_, i) => (isKaydiOlan.includes(i) ? "bilet" : "izsiz"));
const topla = (x) => x.reduce((t, s) => t + yanit[s], 0);
const oran = (n) => (100 * n / (D.length * 3)).toFixed(1);

console.log(`degisiklik ${D.length}   soru ${D.length * 3} (kim / ne zaman / ne degisti)`);
for (const [ad, x] of [["kayittan kurulan ortam", A], ["elle kurulan ortam", B]])
  console.log(`  ${ad.padEnd(22)}: yanitlanan ${topla(x)}/${D.length * 3}` +
    ` (%${oran(topla(x))})   izsiz degisiklik ${x.filter((s) => s === "izsiz").length}`);

const elleGecen = D.filter(([, y]) => y === "elle").map(([k]) => k);
console.log(`kayittan kurulan ortamda kaydi atlayan ${elleGecen.length} degisiklik:`);
for (const k of elleGecen)
  console.log(`  ${k.padEnd(38)} ${kayit.has(k) ? "kayitta var  -> sapma olarak gorunur"
    : "kayitta yok  -> hicbir karsilastirmada cikmaz"}`);
```

```
degisiklik 14   soru 42 (kim / ne zaman / ne degisti)
  kayittan kurulan ortam: yanitlanan 33/42 (%78.6)   izsiz degisiklik 3
  elle kurulan ortam    : yanitlanan 8/42 (%19.0)   izsiz degisiklik 10
kayittan kurulan ortamda kaydi atlayan 3 degisiklik:
  makine.toplayici.erisim_kurali         kayitta yok  -> hicbir karsilastirmada cikmaz
  kuyruk.okuma-kuyrugu.saklama_saat      kayitta var  -> sapma olarak gorunur
  ag.olcum-agi.cikis_yolu                kayitta yok  -> hicbir karsilastirmada cikmaz
```

Kırk iki sorunun otuz üçü kayıt yolunda, sekizi elle yolda yanıtlanıyor. Aradaki fark bir disiplin
farkı değil, bir **saklama yeri** farkıdır: kayıt yolunda değişiklik bir dosyada duruyor ve dosya
sürümleniyor, dolayısıyla üç sorunun üçü de aynı yerden okunuyor. İş kaydı yolunda iki soru
yanıtlanır — kim açtı, ne zaman kapandı — ama üçüncüsü, **ne değişti**, düzyazıya kalır ve
düzyazıda ölçülebilir bir değer yoktur.

Asıl bilgi son üç satırdadır. Kayıttan kurulan ortamda bile üç değişiklik kaydı atladı ve bu üçü
birbirinden farklı sonuç doğurdu. Kayıtta yazılı olan kalem elle değiştirildiğinde bir
karşılaştırma onu **sapma** olarak gösterir; kayıtta yazılı olmayan kalem elle değiştirildiğinde
hiçbir karşılaştırmada çıkmaz. İzlenebilirlik kaydın varlığından değil, **kapsamından** doğuyor:
kaydın dokunmadığı kalemde kayıt yolu ile elle yol arasında hiçbir fark yok.

## Kaydın Bedeli

```bash
#!/usr/bin/env bash
# Kayda baglamanin bedeli: yazilan satir ve degisiklik basina ek adim.
printf 'yazilan satir   talep %s   kayit %s   ayristirici ve uygulayici %s (bir kez)\n' \
  "$(wc -l < talep.txt | tr -d ' ')" "$(wc -l < kayit.alt | tr -d ' ')" \
  "$(wc -l < kur.mjs | tr -d ' ')"
printf 'kayitta %s kalem satiri, %s kalem  -> satir basina %s kalem\n' \
  "$(grep -c '^kaynak' kayit.alt)" "20" "$(node -e 'console.log((20/6).toFixed(2))')"
printf 'degisiklik basina ek adim   elle yol 0   kayit yolu 3 (yaz, gozden gecir, plani oku)\n'
printf 'bir donemde (14 degisiklik)  elle yol 0 ek adim   kayit yolu %s ek adim\n' "$((14 * 3))"
```

```
yazilan satir   talep 12   kayit 8   ayristirici ve uygulayici 38 (bir kez)
kayitta 6 kalem satiri, 20 kalem  -> satir basina 3.33 kalem
degisiklik basina ek adim   elle yol 0   kayit yolu 3 (yaz, gozden gecir, plani oku)
bir donemde (14 degisiklik)  elle yol 0 ek adim   kayit yolu 42 ek adim
```

Kaydın kendisi talepten kısadır: sekiz satır, altısı kalem taşıyor, satır başına 3,33 kalem.
Bedel orada değil. Otuz sekiz satırlık ayrıştırıcı ve uygulayıcı bir kez yazılır ve her ortam için
yeniden kullanılır — bu bir kereliktir. Sürekli ödenen bedel son satırdadır: kayıt yolunda her
değişiklik üç ek adım ister ve bir çeyrekte bu kırk iki ek adıma çıkar. Elle yolda bu adımlar
sıfırdır; bir kişi ortama girer ve değeri değiştirir.

Kırk iki ek adım karşılığında alınan şey de sayılıdır: yirmi beş sorunun daha yanıtlanması ve
yirmi kalemin karşılaştırılabilir olması. Ama alınmayan şey aynı ölçüde nettir. Beş kalem kaydın
dışında kaldı ve kırk iki ek adım onlara dokunmuyor; üç değişiklik kaydı atladı ve ek adımlar
onları da durduramadı. Kayıt bir zorunluluk üretmez, bir **karşılaştırma zemini** üretir — o zemini
kimin kullandığı ayrı bir sorudur ve bu kursun geri kalanı büyük ölçüde onu ölçer.

## Özet

- Aynı ortamın iki kurulumu 9 kalemde ayrıldı: 5 ayrık (talebin sayı vermediği 7 noktanın 5'i),
  1 eksik (yazılıydı, atlandı), 3 fazla (hiçbir tarifte yazılı değil).
- Talebin yedi yorum noktasının ikisi elin yorumu kayıtla aynı değere düştüğü için görünmedi;
  yorum noktası sayısı değişmedi, yalnız bu koşumda ayrılmadılar.
- Kaydın kapsamadığı 5 kalem iki kurulumda da aynı doğdu; bir karşılaştırma bunları hiçbir zaman
  fark olarak göstermez.
- Bir çeyreklik 42 sorunun 33'ü kayıt yolunda, 8'i elle yolda yanıtlandı; farkı yapan şey disiplin
  değil, değişikliğin saklandığı yer.
- Kayıt 8 satır, ayrıştırıcı ve uygulayıcı 38 satır (bir kez); sürekli bedel değişiklik başına
  3 ek adım, bir çeyrekte 42 ek adım.

## Sonraki Adım

Kayıt bu derste bir kalem listesiydi: her satır bir kaynağın niteliklerini sayıyordu ve ortamın ne
**olması gerektiğini** yazıyordu. Bu, kayıt yazmanın tek biçimi değil. Aynı ortam bir adım listesi
olarak da yazılabilir — önce ağı aç, sonra makineleri aç, sonra kuyruğu bağla — ve o liste de bir
dosyada durur, sürümlenir, gözden geçirilir. İki biçim de kayıttır, ikisi de aynı üç ek adımı
ister.

Fark ilk koşumda görünmez. Sonraki ders aynı hedefi iki biçimde yazar ve ikisini **kısmi
başarısızlıkla** koşturur: üçüncü adımda hata çıktığında adım listesi nerede kalıyor, istenen durum
tanımı ne yapıyor; ikisi yeniden koşturulduğunda ne kadar iş üretiyor; ve hedef değiştiğinde her
birinde kaç satır yazmak gerekiyor.
