VPS.TC
| $
Sunucu Durumu
Turkey İstanbul, Türkiye
Aktif
USA New York, ABD
Aktif
Sepet Toplamı:
Sepeti Görüntüle
Cloud-Init Nedir? VPS Kurulumunu Otomatikleştirme
Bulut Bilişim

Cloud-Init Nedir? VPS Kurulumunu Otomatikleştirme

Defne avatarı Defne Eylül 1, 2026 13 dk okuma 0 Yorumlar
Paylaş:

Cloud-init nedir ve VPS kurulumunda ne işe yarar?

Yeni bir VPS açtığınızda ilk birkaç saat çoğu zaman aynı işleri tekrar ederek geçer: paket listelerini güncellemek, yönetim kullanıcısı oluşturmak, SSH anahtarını eklemek, saat dilimini ayarlamak, swap hazırlamak ve temel servisleri kurmak. Bir sunucuda bu büyük bir sorun değildir. Beşinci, onuncu veya aynı özelliklerle açılacak ellinci VPS’te ise elle yapılan her işlem yeni bir hata ihtimali taşır.

Cloud-init burada işe yarar. Linux tabanlı bulut sunucuların ilk açılışta temel işletim sistemi ve kullanıcı ayarlarını otomatik uygulayan servisidir. VPS sağlayıcısından aldığı metadata ile sizin gönderdiğiniz user-data’yı okuyarak hostname, kullanıcı, SSH anahtarı, ağ ayarları, paketler ve ilk çalıştırılacak komutlarla ilgili işlemleri yürütür.

🚀 VPS Sunucu ile Hızınızı Artırın!

Yüksek performanslı SSD depolama ve %99.9 uptime garantisi ile projelerinizi hızlandırın.

Hemen Başla

Kritik ayrıntı şu: Cloud-init çoğu zaman işletim sistemi kurmaz. Sağlayıcının sunduğu cloud image zaten diske yazılmış ve ilk açılışa hazırdır. Cloud-init bu hazır imajı sizin istediğiniz sunucuya dönüştürür.

İlk kullandığımda onu küçük bir Ansible dosyası gibi düşünmüştüm. Kısa sürede yanıldığımı gördüm. Cloud-init makine ilk kez açılırken çalışır; Ansible ise genellikle SSH erişimi hazır olan sisteme sonradan bağlanır. Başlangıç noktaları farklıdır.

İlk açılışta hangi parçalar çalışır?

Cloud-init, dağıtım ve sürüme göre bazı ayrıntıları değişse de işlemleri birkaç aşamada yürütür. Bir VPS’in açılışını incelerken bu sıralamayı bilmek, “kullanıcı neden oluşmadı?” veya “paket kurulumu neden bekliyor?” sorularını daraltır.

☁️ Cloud Sunucu ile Esneklik Kazanın!

Ölçeklenebilir kaynaklar ve anlık yedekleme ile bulutun gücünü deneyimleyin.

Keşfet
  • Generator ve local aşaması: Sistem, cloud-init’in çalışıp çalışmayacağını ve hangi veri kaynağını kullanacağını belirler.
  • Network aşaması: Ağ hazırlandıktan sonra instance metadata ve user-data alınabilir.
  • Config aşaması: Kullanıcılar, SSH anahtarları, paket depoları, hostname ve dosyalar gibi ayarlar uygulanır.
  • Final aşaması: runcmd gibi ilk açılış komutları çalıştırılır. Paket kurulumu tamamlanmadıysa bu aşama beklediğinizden geç bitebilir.

Ubuntu cloud image üzerinde ilgili servisleri şu komutlarla görebilirsiniz:

systemctl status cloud-init-local.service
systemctl status cloud-init.service
systemctl status cloud-config.service
systemctl status cloud-final.service

Son satırdaki servis özellikle değerlidir. runcmd komutları benim kullandığım Ubuntu imajlarında çoğunlukla cloud-final.service aşamasında çalışıyor. Bir testte SSH bağlantısı gelir gelmez sistem hazır sandım; paket kurulumu hâlâ devam ediyordu. Ardından verdiğim komutlar beklenmedik biçimde başarısız oldu. Erken bağlanmak, hazır olmak demek değil.

Cloud image, metadata ve user-data

Cloud-init’i anlamak için üç parçayı ayırın. Cloud image, işletim sisteminin bulut kullanımına hazırlanmış imajıdır. Metadata, makinenin adı, instance kimliği, ağ bilgileri ve sağlayıcıya özgü tanımlardır. User-data ise sizin gönderdiğiniz yapılandırmadır.

Sağlayıcı bu verileri farklı yöntemlerle sunabilir. OpenStack ve birçok ticari bulut platformu metadata servisi kullanır. Evdeki Proxmox laboratuvarımda ise NoCloud veri kaynağıyla çalışıyorum. Bu yöntemde bir seed ISO veya uygun bir disk üzerinde user-data ve meta-data dosyaları bulunur.

Proxmox’taki her sanal makine cloud-init ile kendiliğinden uyumlu olmaz. Bir cloud image indirmeniz, onu template’e dönüştürmeniz, cloud-init diskini eklemeniz ve IP, gateway ile DNS gibi bilgileri sağlamanız gerekir. Hazırlık bir kez yapılır; sonrasında template’ten oluşturulan makinelerde user-data kullanabilirsiniz.

Ben template doğrulamasını bir kez aceleye getirip kapalı VM’den klon aldım. Klon açıldı, fakat hostname ve ağ ayarları beklediğim gibi değildi; seri konsolda eski makineye ait ayarları görüyordum. Sorun user-data’da değil, template’i temizlemeden ve test klonu açmadan kullanmamdaydı. O günden beri her template için küçük bir klon açıyor, hostname, ağ ve SSH erişimini kontrol etmeden onu üretim kaynağı yapmıyorum.

İlk çalışan user-data dosyası

User-data çoğunlukla YAML biçiminde yazılır ve ilk satırda #cloud-config bulunur. YAML girintiye karşı hassastır; sekme kullanmayın. Dosyayı önce bir YAML doğrulayıcıdan geçiriyor, sonra küçük bir test VM’inde deniyorum. Tek boşluk bile yanlış modülün atlanmasına yetebilir.

#cloud-config
hostname: web-01
manage_etc_hosts: true

users:
  - name: deploy
    gecos: Deployment User
    groups: [adm, sudo]
    shell: /bin/bash
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    lock_passwd: true
    ssh_authorized_keys:
      - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... kullanici@laptop

package_update: true
package_upgrade: false
packages:
  - nginx
  - curl
  - vim

write_files:
  - path: /etc/motd
    owner: root:root
    permissions: '0644'
    content: |
      Managed by cloud-init

runcmd:
  - systemctl enable --now nginx
  - [ sh, -c, "echo 'cloud-init tamamlandi' >> /var/log/first-boot.log" ]

Bu örnekte deploy kullanıcısı parola ile giriş yapamıyor, SSH anahtarıyla bağlanıyor ve sudo yetkisine sahip oluyor. Gerçek anahtarı kısaltılmış biçimde gösterdim. User-data sağlayıcı panelinde, metadata servisinde veya seed ISO’da tutulabileceği için özel anahtarınızı kesinlikle bu dosyaya koymayın.

package_update paket listelerini günceller, packages listesi istenen paketleri kurar. package_upgrade: true ilk açılışta bütün sistemi yükseltebilir; üretim template’lerinde bunu gelişigüzel açmıyorum. Kernel veya kritik kütüphane güncellemeleri yeniden başlatma ihtiyacı doğurabilir.

users bölümüyle güvenli başlangıç

Birçok cloud image varsayılan kullanıcıyla gelir. Ubuntu’da bu kullanıcı çoğu zaman ubuntu, Debian imajlarında ise debian olabilir. Sağlayıcının dokümantasyonuna bakmadan doğrudan root ile SSH açmak yerine ilk user-data içinde kişisel bir yönetim kullanıcısı oluşturmayı tercih ederim.

Parola ile SSH erişimini kapatmak için şu ayarları kullanabilirsiniz:

ssh_pwauth: false

users:
  - default
  - name: sysadmin
    groups: [sudo]
    shell: /bin/bash
    lock_passwd: true
    ssh_authorized_keys:
      - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... sysadmin@workstation

users: - default satırı cloud image’ın varsayılan kullanıcısını korur. Bu satırı kaldırdığınızda dağıtıma göre ilk erişim hesabını kaybedebilirsiniz. SSH portunu değiştirmek tek başına güvenlik değildir; doğru anahtar kullanımı, parola girişinin kapatılması, güncel paketler ve firewall kuralları birlikte düşünülmelidir.

Dosya yazma, servis başlatma ve runcmd tuzakları

write_files, ilk açılışta belirli içerikleri belirli dosyalara yazmak için kullanışlıdır. Nginx site tanımı, systemd unit dosyası veya uygulamanın küçük bir konfigürasyonu bu şekilde yerleştirilebilir.

write_files:
  - path: /etc/systemd/system/example.service
    permissions: '0644'
    content: |
      [Unit]
      Description=Example service
      After=network-online.target

      [Service]
      Type=simple
      ExecStart=/usr/local/bin/example
      Restart=on-failure
      User=deploy

      [Install]
      WantedBy=multi-user.target

runcmd:
  - [ systemctl, daemon-reload ]
  - [ systemctl, enable, --now, example.service ]

Servis dosyası yazılmadan önce ilgili binary’nin gerçekten mevcut olduğundan emin olun. write_files dosyayı oluşturur; programı kurmaz. runcmd komutları çalıştırılmak üzere kaydeder ve çoğunlukla final aşamasında yürütür.

Shell değişkenleri ve özel karakterler başka bir tuzaktır. YAML içinde şu kullanım beklediğiniz sonucu vermeyebilir:

runcmd:
  - echo $HOME > /tmp/home.txt

Komutun hangi shell ortamında ve hangi kullanıcıyla çalıştığını varsaymak yerine açık yazın:

runcmd:
  - [ sh, -c, 'printf "%sn" "$HOME" > /tmp/home.txt' ]

Komutları tekrar çalıştırıldığında sistemi bozmayacak şekilde tasarlayın. Bir dosyaya her açılışta satır ekleyen echo ... >> komutu, aynı instance için yeniden çalıştırıldığında gereksiz tekrarlar üretir. Cloud-init ilk kurulum için uygundur; sürekli konfigürasyon yönetimi gerektiğinde Ansible’a geçmek daha temizdir. VPS’te Docker Kurulumu ve İlk Konteyneri Çalıştırma yazısındaki kurulum adımlarını user-data ile başlatabilirsiniz, fakat Docker servisinin ve grup değişikliklerinin ilk açılışta ne zaman etkili olduğunu test etmeden canlı sisteme taşımayın.

Cloud-init ile klasik kurulum script’i aynı şey değil

İlk bakışta ikisi de sunucu açılınca komut çalıştırıyor gibi görünür. Fark, cloud-init’in işletim sistemi ve bulut metadata sürecinin parçası olmasıdır. Sağlayıcının verdiği instance kimliğini, ağ bilgisini ve SSH anahtarlarını kullanabilir; modülleri belirli aşamalarda çalıştırır ve birçok işlem için durum kaydı tutar.

Yöntem Güçlü tarafı Dikkat edilmesi gereken
Cloud-init İlk açılışta kullanıcı, paket ve temel sistem ayarlarını yapar Cloud image ve doğru datasource gerekir
Shell script Basit ve hızlı prototip hazırlanır Hata yönetimi, tekrar çalıştırma ve işlem sırası size kalır
Ansible Tekrarlanabilir, okunabilir ve mevcut makineleri de yönetebilir SSH erişimi, Python ve ayrı bir kontrol makinesi gerekir
Terraform VPS ve ağ gibi altyapı kaynaklarını tanımlar İşletim sistemi içi ayrıntılar için tek başına yeterli değildir

Benim pratik akışım genellikle şöyle: Terraform veya sağlayıcı paneliyle VPS’i oluşturmak, cloud-init ile ilk erişim ve temel güvenliği hazırlamak, ardından Ansible ile uygulama katmanını kurmak. Tek VPS için YAML ve Ansible birlikte fazla gelebilir. Aynı kurulumu üçüncü kez elle yapıyorsanız otomasyon borcunuz birikmiştir.

Cloud-init neden çalışmadı?

İlk bakacağım yer loglardır. Sunucuyu yeniden başlatmak çoğu zaman sorunu çözmez; yalnızca nedenini görmeyi zorlaştırabilir.

cloud-init status --long
cloud-init query ds
journalctl -u cloud-init -u cloud-config -u cloud-final --no-pager
less /var/log/cloud-init.log
less /var/log/cloud-init-output.log

cloud-init status --long çıktısında status: done görmeniz işlemin tamamlandığını söyler; yapılandırmanın doğru olduğu anlamına gelmez. cloud-init-output.log, özellikle runcmd çıktısını ve komutların standart hata mesajlarını bulmak için yararlıdır. Ben bir seferinde “done” satırını başarı kabul edip uygulama servisini kontrol etmeden bilgi verdim. Logun ilerleyen satırlarında paket deposunun DNS çözemediğini gördüm.

cloud-init query ds komutu her imajda aynı çıktıyı vermeyebilir. NoCloud kullanırken metadata dosyasındaki instance kimliği ve seed diskinin bağlantısı önemlidir. Aynı instance ID ile snapshot veya template klonlamak da cloud-init’in bu makineyi daha önce gördüğünü düşünmesine yol açabilir.

YAML biçimini yerel makinenizde kontrol edebilirsiniz:

python3 - <<'PY'
import sys
try:
    import yaml
except ImportError:
    print("PyYAML kurulu değil", file=sys.stderr)
    sys.exit(1)
with open("user-data", encoding="utf-8") as f:
    yaml.safe_load(f)
print("YAML tamam")
PY

Bu kontrol yalnızca YAML sözdizimini doğrular. sudo biçiminin doğru olması, paketin dağıtım deposunda bulunması veya komutun doğru kullanıcıyla çalışması gibi ayrıntıları denetlemez.

Bir kez mi çalışır, tekrar çalıştırılabilir mi?

Cloud-init birçok modül için instance kimliği ve durum dosyaları tutar. User-data’yı değiştirip aynı VPS’i yeniden başlattığınızda bütün ayarların tekrar uygulanmasını beklemeyin. Test sırasında sıfırlamak için şu komut kullanılabilir:

sudo cloud-init clean --logs --seed
sudo reboot

Bu komutu üretim makinesinde rastgele çalıştırmayın. Cloud-init’i yeni bir ilk açılış gibi davranmaya zorlayabilir ve user-data içindeki paket, kullanıcı veya servis işlemlerini yeniden tetikleyebilir. Test VM’inde işe yarayan yöntem, canlı VPS’te bakım planı olmadan uygulanacak bir düzeltme değildir.

Yeni instance oluşturmak çoğu durumda mevcut makinenin state bilgisini silmekten daha güvenlidir. Template hazırlarken cloud-init temizlenmeli, eski SSH host anahtarları ve makineye özel kimlik bilgileri imaja gömülmemelidir.

Güvenlik ve üretim kullanımı

User-data’nın nerede saklandığını biliyor musunuz? Bazı bulut sağlayıcılarında instance metadata servisine yetkili süreçler erişebilir. Panel geçmişi, Terraform state dosyası veya debug çıktısı içinde de user-data kalabilir. Parolaları, API anahtarlarını ve özel SSH anahtarlarını düz metin olarak yazmayın.

  • SSH için parola yerine anahtar tabanlı erişim kullanın.
  • İlk kullanıcıya yalnızca gereken sudo yetkisini verin; mümkünse ayrıcalıklı komutları sınırlayın.
  • API anahtarı gerekiyorsa secret manager, sağlayıcının secret mekanizması veya kısa ömürlü token kullanın.
  • Cloud-init ile kurulan firewall kurallarının mevcut SSH oturumunu kesmeyeceğini test edin.
  • Cloud image ve cloud-init paketini güncel tutun, fakat yükseltmeyi kontrolsüz biçimde tüm üretim makinelerine yaymayın.
  • İlk açılış loglarında token, parola veya özel anahtar kalmadığını kontrol edin.

Temel güvenlik adımlarını otomasyona eklemek istiyorsanız Linux Sunucu Güvenliği için Zorunlu 10 Temel Adım yazısındaki maddeleri user-data ve Ansible görevlerine ayırabilirsiniz. Ben firewall ve SSH ayarını cloud-init ile mümkün olduğunca erken yapıyorum; uygulama servislerinin ayrıntılarını daha sonra yönetiyorum. İlk açılış başarısız olsa bile erişim ve teşhis kanalları böylece daha belirgin kalıyor.

Gerçek bir VPS akışı nasıl görünür?

Ubuntu 24.04 cloud image üzerinden web sunucusu açacağınızı düşünelim. Önce sağlayıcının cloud-init desteğini, kabul ettiği user-data biçimini ve ağ ayarlarının otomatik verilip verilmediğini kontrol edin. Ardından küçük bir yapılandırmayla başlayın: kullanıcı, SSH anahtarı, hostname ve tek bir test paketi.

#cloud-config
hostname: web-01
fqdn: web-01.example.net
manage_etc_hosts: true
ssh_pwauth: false
package_update: true
packages:
  - nginx

users:
  - default
  - name: deploy
    groups: [sudo]
    shell: /bin/bash
    lock_passwd: true
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    ssh_authorized_keys:
      - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... deploy@laptop

runcmd:
  - [ systemctl, enable, --now, nginx ]
  - [ sh, -c, "printf '%sn' 'first boot ok' > /var/log/first-boot-check.log" ]

Makineye bağlandıktan sonra yalnızca Nginx’in çalışmasına bakmayın. Kullanıcı anahtarla giriş yapabiliyor mu, hostname doğru mu, apt işlemi tamamlandı mı, cloud-init hata kaydetmiş mi kontrol edin:

hostnamectl
id deploy
sudo systemctl is-active nginx
sudo cloud-init status --long
sudo tail -n 30 /var/log/cloud-init-output.log

Bu kontrolleri bir shell script’i veya Ansible doğrulama görevi haline getirebilirsiniz. VPS’te MySQL Kurulumu ve Güvenli Yapılandırma gibi hassas servislerde uzun bir runcmd listesi yerine önce temel sistemi kurup ardından konfigürasyon yönetimiyle ilerlemeyi daha güvenli buluyorum. MySQL root parolasını user-data’ya koymak özellikle kötü bir fikirdir.

Hangi işleri cloud-init’e bırakmalısınız?

İlk açılışın doğasına uygun işler kısa, öngörülebilir ve makinenin temel erişimiyle ilgili olmalı. Kullanıcı oluşturma, SSH anahtarı, hostname, timezone, paket deposu, birkaç paket ve basit systemd aktivasyonu iyi adaylardır.

Uygulamanın bütün dağıtımını tek bir runcmd bloğuna sıkıştırmak kırılgan bir yapı kurar. Uzun Docker Compose kurulumları, veritabanı şemaları, dış servislere ait secret’lar ve başarısız olduğunda geri alma gerektiren migration işlemleri için ayrı bir süreç kullanın. Cloud-init başarısız bir komutun ardından sonraki komutları çalıştırmaya devam edebilir; bunu shell mantığıyla ayrıca kontrol etmeniz gerekir.

runcmd:
  - [ sh, -c, 'set -euxo pipefail; /usr/local/bin/bootstrap-app' ]

Buradaki set -euxo pipefail hata ayıklamayı kolaylaştırabilir, fakat her script için körlemesine uygun değildir. Secret içeren değişkenler -x ile loglara yazılabilir. Üretim user-data’sında hata görünürlüğüyle gizlilik arasında denge kurun.

İmaj hazırlarken cloud-init temizlenmeli, template’in her klonda yeni bir instance gibi davranması sağlanmalı ve SSH host anahtarlarının yeniden üretilmesi planlanmalıdır. Proxmox’ta template’i kapatmadan klon almak gibi aceleci işlemler, aynı hostname veya eski ağ bilgisinin iki makinede görünmesine yol açabilir. Ben template’i kapattıktan sonra test klonu açıyor, seri konsol ve SSH üzerinden doğrulama yapıyorum.

Cloud-init kullanmaya nereden başlamalı?

Önce sağlayıcınızın sunduğu tek bir Ubuntu veya Debian cloud image seçin. İki dağıtımı aynı user-data ile yönetmeye çalışmak, paket adları ve varsayılan kullanıcılar yüzünden gereksiz karmaşa çıkarır. Küçük bir dosya yazın; kullanıcı ve SSH anahtarı çalışmadan Nginx, Docker veya veritabanı kurulumuna geçmeyin.

Dosyayı sürüm kontrolünde tutacaksanız gerçek anahtarları ve secret’ları depoya göndermeyin. Template’in cloud-init loglarını ve servis durumlarını izleyin. Başarılı bir ilk açılış yalnızca VPS’in ping’e cevap vermesi değildir; beklenen kullanıcıyla güvenli giriş, doğru hostname, tamamlanmış paket kurulumu ve temiz loglar birlikte değerlendirilmelidir.

Cloud-init nedir sorusunun pratik cevabı benim için şu: VPS’in ilk açılışını tekrarlanabilir, denetlenebilir ve daha az elle müdahale gerektiren bir sürece çeviren başlangıç otomasyon katmanıdır. Her işi onun içine koymam. Doğru sınırı çizdiğinizde aynı kurulumu üçüncü kez yaparken hem zaman hem hata payı kazanırsınız. Yine de son kontrolü atlamıyorum; otomasyon, kontrol listesinin yerini almıyor, onu daha güvenilir hale getiriyor.

Sık Sorulan Sorular

Cloud-init tüm VPS’lerde çalışır mı?

Hayır. Sağlayıcının cloud-init desteği, kullanılan cloud image ve veri kaynağının doğru yapılandırılması gerekir. Klasik ISO ile kurulmuş her VPS’te cloud-init otomatik olarak hazır gelmeyebilir.

Cloud-init ile parola belirlemek güvenli mi?

Parolayı user-data içinde düz metin tutmak güvenli değildir; dosya panel geçmişinde veya metadata servisinde kalabilir. SSH anahtarı kullanın, parola ile SSH girişini kapatın ve gerekiyorsa secret yönetimi için ayrı bir mekanizma tercih edin.

Cloud-init komutları her reboot sonrasında tekrar çalışır mı?

Genellikle hayır. Birçok modül instance kimliği ve durum kayıtları sayesinde ilk açılışta bir kez çalışır. Yeniden çalıştırma ihtiyacı varsa modül davranışını ve cloud-init clean etkisini test VM’inde doğrulayın.

Cloud-init ile Ansible arasındaki fark nedir?

Cloud-init, makinenin ilk açılışında temel sistemi ve erişimi hazırlamak için uygundur. Ansible ise SSH üzerinden mevcut makinelerde daha ayrıntılı, tekrarlanabilir ve sürekli konfigürasyon yönetimi sağlar. Pratikte ikisini arka arkaya kullanmak çoğu ortamda daha sağlıklıdır.

Defne avatarı
Yazar

Defne

vps.tc blog yazarı. Sistem yönetimi, Linux ve hosting dünyası üzerine yazıyor.

İlgili Yazılar