ClientNodetonetDeviceTarget TERRAFORM nodetonet.com
Integration Terraform IaC REST API

Terraform ile Nodetonet — proxy'leri http veya null_resource ile kod olarak yönet

Terraform planından Nodetonet mobil proxy ve HTTP tünellerini hashicorp/http ile okuma, null_resource local-exec ile yazma kullanarak bildirgesel olarak yönetin.

N Nodetonet Team
15 Mayıs 2026 9 dk okuma

Uzun ömürlü altyapıyı yönetmenin doğru yolu deklaratiftir. Ortamında staging URL'leri, webhook alıcıları ve kiracı başına proxy'ler varsa, ekip her yeni servis eklediğinde bir runbook'tan curl POST /api/v1/proxies yapmak istemezsin. Bunu cloud kaynaklarının yanında bir main.tf'de istiyorsun — terraform plan diff'i göstersin, terraform apply değişikliği uygulasın.

Kısa özet: Nodetonet REST API'si tamamen betiklenebilir. İki standart Terraform primitifi — okuma için hashicorp/http ve yazma için local-exec'li null_resource — özel bir sağlayıcı beklemeden bugün mobil proxy'leri, dönen proxy havuzlarını ve HTTP tünellerini kod olarak yönetmeni sağlar.

Proxy'leri neden kod olarak yönetmeli?

Altyapıyı-kod-olarak (IaC) yaklaşımı sadece bir DevOps trendi değil — proxy yoğun iş yükleri için gerçek operasyonel sorunları çözer:

Nodetonet'in perde arkasında trafiği nasıl yönlendirdiğine dair bağlam için Nodetonet trafiği nasıl yönlendirir yazısına bak. Terraform'a dalmadan önce REST API temellerini öğrenmek için ilk REST API çağrın rehberini oku.

1 · Minimum providers bloğu

http, built-in null ve (isteğe bağlı) unique subdomain ekleri için random'a ihtiyacın var. Private registry yok, plugin kurulum dansı yok:

terraform {
  required_version = ">= 1.6"
  required_providers {
    http   = { source = "hashicorp/http",   version = "~> 3.4" }
    null   = { source = "hashicorp/null",   version = "~> 3.2" }
    random = { source = "hashicorp/random", version = "~> 3.6" }
  }
}

variable "nodetonet_token" {
  type      = string
  sensitive = true
}

locals {
  api_base = "https://nodetonet.com/api/v1"
  headers = {
    Authorization = "Bearer ${var.nodetonet_token}"
    Content-Type  = "application/json"
  }
}

Token'ı TF_VAR_nodetonet_token=$NTN_TOKEN terraform apply ile geç veya mevcut secret backend'inde sakla (AWS Secrets Manager, Vault, Doppler) ve bir data source ile çek. API token'ını hesabından API Anahtarları bölümünden oluşturabilirsin — şifre gibi davran: Terraform'da sensitive, kasanda sakla, asla versiyon kontrolüne koyma.

2 · Proxy oluşturma

"Oluşturma" yarısı iki provisioner'lı bir null_resource: create'te local-exec POST /api/v1/proxies çağırır, destroy'da local-exec DELETE çağırır. İşin püf noktası dönen id'yi yakalamak — destroy'un ne silineceğini bilmesi gerekir. triggers ve küçük bir state dosyası kullanıyoruz:

resource "random_string" "sub_suffix" {
  length  = 6
  upper   = false
  special = false
}

resource "null_resource" "tunnel_api" {
  triggers = {
    subdomain = "api-${random_string.sub_suffix.result}"
    port      = 8080
    state_dir = "${path.module}/.terraform-nodetonet"
  }

  provisioner "local-exec" {
    command = <<-EOT
      mkdir -p ${self.triggers.state_dir}
      RESP=$(curl -fsS -X POST ${local.api_base}/proxies \
        -H "Authorization: Bearer ${var.nodetonet_token}" \
        -H "Content-Type: application/json" \
        -d '{
          "subdomain": "${self.triggers.subdomain}",
          "target_host": "127.0.0.1",
          "target_port": ${self.triggers.port}
        }')
      echo "$RESP" > ${self.triggers.state_dir}/${self.triggers.subdomain}.json
    EOT
  }

  provisioner "local-exec" {
    when    = destroy
    command = <<-EOT
      ID=$(jq -r .id ${self.triggers.state_dir}/${self.triggers.subdomain}.json)
      curl -fsS -X DELETE \
        -H "Authorization: Bearer ${var.nodetonet_token}" \
        https://nodetonet.com/api/v1/proxies/$ID
      rm -f ${self.triggers.state_dir}/${self.triggers.subdomain}.json
    EOT
  }
}

triggers input'ları Terraform state'ine hashler. Sonraki plan'da port'u değiştirirsen Terraform drift'i algılar ve create provisioner'ını tekrar çalıştırır — yeni port'la API'mizi çağırır. Bu gerçek bir "update" değil (yok eder ve yeniden oluşturur) ama ephemeral tüneller için gayet yeterli.

3 · State okuma — http data source

Okumalar için (state'i değiştirmemesi gereken her şey için) http daha temiz. Proxy'leri listele, dışarıda oluşturduğun birinin URL'ini bul veya başka bir kaynağa input olarak ver:

data "http" "proxies" {
  url = "${local.api_base}/proxies"
  request_headers = local.headers
}

locals {
  proxies = jsondecode(data.http.proxies.response_body)
}

output "all_urls" {
  value = [for p in local.proxies : p.url]
}

Bunu yukarıdaki null_resource ile eşleştirerek az önce oluşturduğun proxy'nin URL'ini içeren output'lar yap:

locals {
  created = jsondecode(file(
    "${null_resource.tunnel_api.triggers.state_dir}/${null_resource.tunnel_api.triggers.subdomain}.json"
  ))
}

output "tunnel_url" {
  value = local.created.url
}

output "tunnel_id" {
  value = local.created.id
}

4 · Hepsini bir araya getirmek — tam bir main.tf

Kopyala/yapıştır, terraform init && terraform apply çalıştır ve başka yerde tanımlayacağın bir servise yönlendirilmiş bir tünelle kal:

terraform {
  required_version = ">= 1.6"
  required_providers {
    null   = { source = "hashicorp/null",   version = "~> 3.2" }
    random = { source = "hashicorp/random", version = "~> 3.6" }
  }
}

variable "nodetonet_token" { type = string, sensitive = true }
variable "service_port"    { type = number, default = 3000 }
variable "service_name"    { type = string }

resource "random_string" "suffix" {
  length = 6, upper = false, special = false
}

resource "null_resource" "tunnel" {
  triggers = {
    name = "${var.service_name}-${random_string.suffix.result}"
    port = var.service_port
  }

  provisioner "local-exec" {
    command = "curl -fsS -X POST https://nodetonet.com/api/v1/proxies -H 'Authorization: Bearer ${var.nodetonet_token}' -H 'Content-Type: application/json' -d '{"subdomain":"${self.triggers.name}","target_port":${self.triggers.port}}' | tee ${path.module}/.tunnel-${self.triggers.name}.json"
  }

  provisioner "local-exec" {
    when    = destroy
    command = "curl -fsS -X DELETE -H 'Authorization: Bearer ${var.nodetonet_token}' https://nodetonet.com/api/v1/proxies/$(jq -r .id ${path.module}/.tunnel-${self.triggers.name}.json) && rm -f ${path.module}/.tunnel-${self.triggers.name}.json"
  }
}

output "url" {
  value = jsondecode(file("${path.module}/.tunnel-${null_resource.tunnel.triggers.name}.json")).url
}

terraform apply -var="service_name=stripe-test" ile çalıştır. terraform destroy ile yok et — when = destroy provisioner'ı DELETE çağırır.

5 · Dönen proxy havuzlarını Terraform ile yönetmek

Tek tünellerin ötesinde, Nodetonet'in dönen proxy havuzları (token grupları olarak adlandırılır) da API üzerinden yönetilebilir. Token grubu, istemcilerin tek bir uç nokta aracılığıyla bağlandığı adlandırılmış bir mobil cihaz havuzudur — Nodetonet, cihaz çevrimdışı olduğunda otomatik yük devretme ile round-robin veya en-az-bağlantı seçimi kullanarak bir cihaz seçer.

Aynı null_resource deseni geçerlidir. Bir grup oluştur, dönen grup id'sini sakla, müşteri başına kimlik bilgileri oluştururken ona başvur. API, aşağı akış tüketicilerine verdiğin proxy uç noktasını, kullanıcı adını ve şifreyi döndürür. Bu, birden çok müşteri için proxy yöneten ekiplerin — örneğin beyaz etiket bayi hesapları aracılığıyla — tüm müşteri topolojisini versiyon kontrolüne alabilme yoludur.

Terraform yazmadan önce token gruplarının ve havuzlarının kavramsal bir özetini görmek için token grupları: havuz oluşturma yazısına bak.

6 · DIY vs resmi sağlayıcı — karşılaştırma

Dürüst olalım: null_resource yaklaşımı çalışıyor ama güzel değil. Gerçek bir sağlayıcının gerisinde kaldığı ve gayet yeterli olduğu yerler:

Yeteneknull_resource + curl (bugün)Resmi sağlayıcı (yol haritası)
Kaynak oluşturma / silmeEvet, local-exec ileEvet, yerel kaynak yaşam döngüsü
Mevcut durumu okumaEvet, http data source ileEvet, tipli data source'lar
Drift tespitiKısmi — trigger'lar değişiklikleri hashler, panel düzenlemelerini değilTam — refresh bant dışı değişiklikleri tespit eder
Yerinde güncellemeler (PATCH)Hayır — yok et + yeniden oluşturEvet, alan-bazlı granülarite
İnsan tarafından okunabilir plan diff'leriMinimal ("will be replaced")Tam alan-bazlı diff
Tipli kaynak şemasıHayır — ham JSON stringleriEvet — doğrulanmış girdiler
Terraform Cloud ile çalışırEvet, uzak state geçici çözümüyleEvet, yerel olarak
Gerekli harici araçlarRunner'da curl, jqHiçbiri

1–5 uzun ömürlü tünel yönetiyorsan DIY yaklaşımı gayet yeterli. Çoklu kiracı boyunca 50+ kaynak yönetiyorsan gerçek sağlayıcıyı bekle — veya support@nodetonet.com'a ulaş ve kullanım durumunu anlat; kurumsal zaman çizelgeleri esnektir.

7 · Resmi Terraform sağlayıcısı yol haritasında

Terraform provider · 2026 4. çeyrek. Yayınlandığında yukarıdaki tüm main.tf'in eşdeğeri şu olur:

provider "nodetonet" {
  token = var.nodetonet_token
}

resource "nodetonet_proxy" "api" {
  subdomain   = "stripe-test"
  target_host = "127.0.0.1"
  target_port = 3000
}

output "url" {
  value = nodetonet_proxy.api.url
}

Altta aynı REST API; sağlayıcı sadece düzgün drift algılama, yerinde PATCH ve tipli şema ile sarar. null_resource desenini kullanan mevcut main.tf dosyaları çalışmaya devam edecek — birer birer geçiş yapabilirsin.

8 · CI/CD entegrasyon ipuçları

Curl yaklaşımını otomasyonda çalıştırırken ekiplerin takıldığı birkaç pratik detay:

Hemen başla

Yukarıdaki main.tf'i yapıştır, token'ını ayarla ve terraform apply çalıştır. İlk bildirgesel proxy'n iki dakika uzakta. Soruların mı var? İletişim'i ziyaret et, discord.gg/nodetonet'e katıl ya da belirli özellikler için daha derin rehberler için blog'a göz at. Python'la proxy oluşturmayı betiklemek istersen, Python ile programatik tünel oluşturma'ya bak.

Sıkça sorulan sorular

.tunnel-*.json state dosyalarını commit etmeli miyim?
Hayır — .tunnel-*.json'u .gitignore'a ekle. Onlar lokal state, gerçeklik kaynağı değil. Terraform state dosyası (terraform.tfstate) null_resource varlığını izler; JSON dosyaları sadece destroy provisioner için dönen id'yi cache'lediğimiz yer. path.module numarasıyla workspace başına tut.
curl yaklaşımıyla Terraform Cloud veya Atlantis kullanabilir miyim?
Evet — her ikisi de curl ve jq'nun mevcut olduğu bir sandbox'ta plan çalıştırır. TF_VAR_nodetonet_token'u hassas bir workspace değişkeni olarak ayarla. Tek uyarı: lokal cache dosyaları (.tunnel-*.json) koşular arasında kalıcı olmaz, yani yeni bir runner'da destroy id'yi bulamayabilir. Bunu sağlamlaştırmak için uzak bir KV store kullan veya id'yi bir local_file kaynağı olarak Terraform state'e yaz.
Resmi Terraform sağlayıcısı open source olacak mı?
Evet. Sağlayıcı Mozilla Public License altında yayınlanacak — çoğu Terraform sağlayıcısıyla aynı. Fork'lanmış sürümünü vendor'layabilir, kodu denetleyebilir veya upstream'e katkıda bulunabilirsin. Sardığı REST API public, yani herhangi bir üçüncü taraf da sağlayıcı yazabilir; bizimki kanonik olan olacak.
Terraform aracılığıyla dönen proxy havuzlarını (token grupları) yönetebilir miyim?
Evet. Nodetonet'in token grupları REST API üzerinden sunulur, bu yüzden aynı null_resource deseniyle havuzları oluşturabilir, yapılandırabilir ve kaldırabilirsin. Dönen grup id'sini lokal bir dosyada sakla ve müşteri başına kimlik bilgileri sağlarken ona başvur. Tam API şekli için token grubu havuzu oluşturma rehberimize bak.
Terraform'da Nodetonet API kimlik doğrulamasını nasıl yönetirim?
Hassas bir Terraform değişkeni (variable "nodetonet_token" { sensitive = true }) tanımla ve TF_VAR_nodetonet_token veya bir secrets manager data source üzerinden geç. Token'ları asla .tf dosyalarına sabit kodlama. Resmi sağlayıcı yayınlandığında, kimlik doğrulama aynı token'la bir provider "nodetonet" bloğunda yapılandırılacak.
Programatik proxy yönetimi için Python alternatifi var mı?
Evet. Terraform kullanım durumunun gerektirdiğinden daha ağırsa, aynı REST API'yi requests kütüphanesiyle Python'dan çalıştırabilirsin. Tam çalışan bir örnek için Python ile programatik tünel oluşturma rehberimize bak.
Nodetonet paneli kaynağı değiştirirse Terraform ile yönetilen proxy'lerime ne olur?
Mevcut null_resource yaklaşımıyla Terraform, sonraki plan'da panel değişikliğini tespit etmez — sadece triggers haritası değişirse fark eder. Resmi sağlayıcı bunu düzgün drift tespiti ile çözecek: bir terraform refresh veya plan -refresh-only canlı durumu çekecek ve farklılığı gösterecek.

Nodetonet proxy'lerini kod olarak yönetin

Yukarıdaki main.tf'i yapıştırın ve terraform apply çalıştırın. İlk bildirimsel proxy'niz iki dakika uzakta.