Blog'a dön
•
ByteGurus

Terraform ile Kod Olarak Altyapı

Terraform ve OpenTofu ile kod olarak altyapı: ilk yapılandırma, uzak durum ve kilitleme, modüller, ortam ayrımı, sır yönetimi ve sık yapılan hatalar.

Terraform OpenTofu IaC DevOps Bulut

Altyapıyı bulut konsolunda tıklayarak yönetmek hem yavaş hem risklidir: kimin neyi ne zaman değiştirdiği bilinmez, aynı ortamı ikinci kez kurmak zordur. Kod olarak altyapı (Infrastructure as Code, IaC) bu sorunu, altyapıyı uygulama kodu gibi sürümlenen, gözden geçirilen ve tekrar üretilebilen dosyalarla tanımlayarak çözer. Bu rehber Terraform ile nasıl başlanacağını ve ekip olarak nasıl sürdürüleceğini anlatıyor.

Kod olarak altyapı nedir

Altyapıyı (ağlar, sunucular, veritabanları, DNS kayıtları) elle kurmak yerine istenen durumu tanımlayan dosyalar yazarsınız; araç mevcut durumla karşılaştırıp gereken değişiklikleri uygular. Altyapı böylece sürümlenir, tekrar üretilebilir ve denetlenebilir hâle gelir.

Neden Terraform ve OpenTofu

Çok sağlayıcı desteği: AWS, Azure, Google Cloud, Cloudflare ve yüzlerce başka sağlayıcı aynı dille yönetilir.

Bildirimsel dil: HCL ile nasıl yapılacağını değil, ne istediğinizi yazarsınız; adımları araç çıkarır.

Durum yönetimi: araç, gerçek altyapının bir kopyasını durum (state) dosyasında tutar ve değişiklikleri bu kopyaya göre hesaplar.

Ekosistem: hazır modül kayıtları ve geniş topluluk.

Lisans notu: HashiCorp 2023’te Terraform’un lisansını açık kaynak MPL’den BSL’ye değiştirdi. Bunun üzerine Linux Foundation çatısı altında açık kaynak bir çatal olan OpenTofu doğdu. İkisi büyük ölçüde aynı dili ve sağlayıcıları kullanır; aşağıdaki örnekler terraform yerine tofu komutuyla da çalışır. Hangisini seçeceğiniz kurumunuzun lisans politikasına bağlıdır.

Başlangıç

macOS’te kurulum:

brew install hashicorp/tap/terraform   # ya da: brew install opentofu
terraform version

İlk yapılandırma (main.tf):

terraform {
  required_version = ">= 1.10"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.region
}

Temel akış her zaman aynıdır:

terraform init     # sağlayıcıları indir, arka ucu bağla
terraform plan     # ne değişecek?
terraform apply    # planı uygula

Gerçekçi bir örnek: veritabanı

Küçük bir uygulamanın PostgreSQL veritabanı:

resource "aws_db_instance" "postgres" {
  identifier        = "${var.environment}-app-db"
  engine            = "postgres"
  engine_version    = "16"
  instance_class    = "db.t4g.micro"
  allocated_storage = 20

  db_name  = "appdb"
  username = "app_admin"
  manage_master_user_password = true   # parola AWS Secrets Manager'da üretilir, durum dosyasına düşmez

  storage_encrypted       = true
  backup_retention_period = 7
  deletion_protection     = var.environment == "production"
  skip_final_snapshot     = var.environment != "production"

  tags = { Environment = var.environment }
}

Dikkat edilecek iki nokta: parola koda ya da değişkene yazılmaz, sağlayıcının sır yöneticisine bırakılır; üretimde silme koruması açıktır ve son yedek alınmadan veritabanı silinmez.

Durumu yönetmek

Durum dosyası altyapının haritasıdır ve çoğu zaman hassas bilgi içerir. Ekip çalışmasında yerel tutulmaz; şifreli, sürümlenen ve kilitlenen bir uzak arka uçta saklanır:

terraform {
  backend "s3" {
    bucket       = "acme-terraform-state"
    key          = "production/app.tfstate"
    region       = "eu-central-1"
    encrypt      = true
    use_lockfile = true   # S3 üzerinde yerel kilit; ayrı DynamoDB tablosu gerekmez
  }
}

Kilitleme, iki kişinin aynı anda apply çalıştırıp altyapıyı bozmasını engeller. Durum kovasına erişimi de sınırlayın: durumu okuyabilen kişi içindeki sırları da okuyabilir.

Modüller

Altyapı büyüdükçe birlikte kullanılan kaynakları modüllerde toplayın:

modules/
├── network/
├── database/
└── compute/
environments/
├── staging/
│   └── main.tf
└── production/
    └── main.tf
module "network" {
  source      = "../../modules/network"
  vpc_cidr    = "10.0.0.0/16"
  environment = "production"
}

module "database" {
  source      = "../../modules/database"
  subnet_ids  = module.network.private_subnet_ids
  environment = "production"
}

Ortamları ayrı dizinlerde ve ayrı durum dosyalarıyla tutmak, workspace kullanmaktan daha güvenli bir ayrım sağlar: hazırlık ortamındaki bir hata üretim durumuna dokunamaz ve her ortama farklı erişim izni verilebilir.

İyi uygulamalar

Sürüm kontrolü: tüm .tf dosyaları Git’te; durum dosyaları ve sır içeren .tfvars dosyaları asla.

Gözden geçirme: altyapı değişikliği de pull request ile gelir; plan çıktısı incelemeye eklenir.

Otomasyon: apply bir geliştiricinin dizüstü bilgisayarından değil, CI ya da bir kontrolcü (Atlantis, Flux için tofu-controller gibi) üzerinden çalışır.

Sürüm sabitleme: sağlayıcı ve modül sürümleri sabitlenir, kilit dosyası (.terraform.lock.hcl) Git’e girer.

Test ve denetim: terraform validate, tflint ve tfsec ya da Checkov gibi güvenlik taramaları.

Belgeleme: neyin değil, neden öyle kurulduğunun yazılması.

Sık yapılan hatalar

Plan’ı atlamak: apply öncesi plan okunmadan değişiklik uygulanır.

Sırları koda yazmak: parolalar ve anahtarlar sır yöneticisinde durur; durum dosyasına düşen sırlar da unutulmamalıdır.

Elle değişiklik: konsoldan yapılan değişiklik bir sonraki plan’da sapma (drift) olarak görünür ya da geri alınır. Sapmayı düzenli plan çalıştırarak yakalayın.

Tutarsız adlandırma: ortam ve amacı içeren tutarlı adlar, kaynakların sahibini bulmayı kolaylaştırır.

Sonuç

Terraform ve OpenTofu, altyapıyı tekrar üretilebilir, gözden geçirilebilir ve denetlenebilir kılar. Küçük bir parçayla başlayın, durumu en baştan uzakta ve kilitli tutun, değişiklikleri kod gibi gözden geçirin.

Altyapınızı koda taşımayı birlikte planlamak isterseniz bize yazın.

B

ByteGurus

Yazar

Tüm yazılara dön
Başlamaya hazır mısınız?

Projenize başlamaya hazır mısınız?

Fikirlerinizi hayata geçirmek için size nasıl yardımcı olabileceğimizi konuşalım.