Terraform Input ve Output Variables / Değişkenler

Terraform input ve output variables (değişkenler), merkezi olarak kontrol edilen yeniden kullanılabilir değerleri tanımlamanın harika bir yoludur. Terraform değişkenlerindeki bilgiler, dağıtım planlarından bağımsız olarak kaydedilir, bu da değerlerin tek bir dosyadan okunmasını ve düzenlenmesini kolaylaştırır.

Bir önceki yazımız olan Terraform İle AWS Kullanımı ve EC2 Web Server Deploy başlıklı yazıda yer alan web server kodunun, hem güvenlik grubunda hem de User Data yapılandırmasında 8080 bağlantı noktasına sahip olduğunu fark etmiş olabilirsiniz. Bu, Don't Repeat Yourself (DRY) ilkesini ihlal eder. Her bilgi parçasının bir sistem içinde tek ve açık bir temsili olmalıdır. Eğer bir değişken kullanmazsanız, port numarası değeri birden fazla yerde olduğundan, bu değeri güncellemeniz gerektiğinde her yerde aynı değişiklikleri yapmak zorunda kalırsınız.

1. Input Variable / Değişken Tanımlamak

Kodunuzu daha DRY ve daha yapılandırılabilir hale getirmek için Terraform, değişkenler tanımlamanıza izin verir. İşte bir değişken bildirmek için syntax şu şekildedir:

variable "NAME" {
  [CONFIG ...]
}

Değişken bildiriminin gövdesi, aşağıdaki isteğe bağlı parametreleri içerebilir:

  • description: Bir değişkenin nasıl kullanıldığını belgelemek için bu parametreyi kullanmak her zaman iyi bir fikirdir. Takım arkadaşlarınız bu açıklamayı sadece kodu okurken değil, aynı zamanda plan ve apply komutlarını çalıştırırken de görebilecekler.
  • default: Değişken için bir değer sağlamanın, komut satırından (-var seçeneğini kullanarak), bir dosya aracılığıyla (-var-file seçeneğini kullanarak) veya bir ortam değişkeni (Terraform, TF_VAR_<variable_name> adındaki ortam değişkenlerini arar) aracılığıyla iletmek de dahil olmak üzere birkaç yolu vardır. Herhangi bir değer sağlanmazsa, değişken bu varsayılan değere geri döner. Varsayılan değer yoksa, Terraform etkileşimli olarak kullanıcıdan bir tane isteyecektir.
  • type: Bu, bir kullanıcının girdiği değişkenler üzerinde değişken tipi kısıtlaması uygulamanıza olanak tanır. Terraform, string, number, bool, list, map, set, object, tuple, ve any dahil olmak üzere bir dizi değişken tipi kısıtlamasını destekler. Basit hataları yakalamak için bir tip kısıtlaması tanımlamak her zaman iyi bir fikirdir. Bir tip belirtmezseniz, Terraform tipin herhangi biri olduğunu varsayar.
  • validation: Bu, bir sayı üzerinde minimum veya maksimum değerleri sınırlamak gibi temel tip kontrollerinin ötesine geçen özel doğrulama kuralları tanımlamanıza izin verir
  • sensitive: Bu parametreyi bir değişkende true olarak ayarlarsanız, plan veya apply komutu çalıştırdığınızda Terraform bunu loga kaydetmez. Bunu, değişkenler aracılığıyla Terraform kodunuza ilettiğiniz tüm secretlarda kullanmalısınız. Ör. şifreler, API anahtarları, vs.

2. Input Variable / Değişken Tipleri

Öyleyse her bir değişken tipi için örnekleri göstermeye başlayalım:


String Variable / Değişkeni: Girdiğiniz değerin bir karakter dizisi olduğunu kontrol eden bir değişken örneği:

variable "string_example" {
  description = "An example of a string variable in Terraform"
  type        = string
  default     = "Kerteriz Blog"
}

Number Variable / Sayı Değişkeni: Girdiğiniz değerin bir sayı olduğunu kontrol eden bir değişken örneği:

variable "number_example" {
  description = "An example of a number variable in Terraform"
  type        = number
  default     = 42
}

Boolean Variable / Mantıksal Değişkeni: Girdiğiniz değerin true veya false olduğunu kontrol eden bir değişken örneği:

variable "boolean_example" {
  description = "An example of a boolean variable in Terraform"
  type        = bool
  default     = true
}

List Variable / Liste Değişkeni: Değerin bir liste olup olmadığını kontrol eden bir değişken örneği:

variable "list_example" {
  description = "An example of a list in Terraform"
  type        = list
  default     = ["a", "b", "c"]
}

Number List Variable / Sayı Listesi Değişkeni: Tip kısıtlamalarını da birleştirebilirsiniz. Örneğin, listedeki tüm öğelerin sayı olmasını gerektiren bir liste girdi değişkeni:

variable "list_numeric_example" {
  description = "An example of a numeric list in Terraform"
  type        = list(number)
  default     = [1, 2, 3]
}

Map Variable / Değişkeni: İşte tüm değerlerin string olmasını gerektiren bir map:

variable "map_example" {
  description = "An example of a map in Terraform"
  type        = map(string)

  default = {
    key1 = "value1"
    key2 = "value2"
    key3 = "value3"
  }
}

Object Variable / Nesne Değişkeni: Nesne tipi kısıtlamasını kullanarak daha karmaşık yapısal tipler de oluşturabilirsiniz:

variable "object_example" {
  description = "An example of a structural type in Terraform"
  type        = object({
    name    = string
    age     = number
    tags    = list(string)
    enabled = bool
  })

  default = {
    name    = "value1"
    age     = 42
    tags    = ["a", "b", "c"]
    enabled = true
  }
}

3. Input Variable / Değişken Değerlerini Ayarlamak

Web sunucusu örneğine geri dönersek, ihtiyacınız olan şey port numarasını saklayan bir değişkendir:

variable "server_port" {
  description = "The port the server will use for HTTP requests"
  type        = number
}

server_port değişkeninin varsayılanı olmadığını unutmayın, bu nedenle şimdi apply komutunu çalıştırırsanız, Terraform interaktif olarak server_port için bir değer girmenizi isteyecek ve değişkenin açıklamasını size gösterecektir:

$ terraform apply

var.server_port
  The port the server will use for HTTP requests

  Enter a value:

Etkileşimli bir bilgi istemiyle uğraşmak istemiyorsanız, -var komut satırı seçeneği aracılığıyla değişken için bir değer sağlayabilirsiniz:

terraform plan -var "server_port=8080"

Değişkeni, TF_VAR_<name> adlı bir ortam değişkeni aracılığıyla da ayarlayabilirsiniz. Burada <name>, ayarlamaya çalıştığınız değişkenin adıdır:

export TF_VAR_server_port=8080	# LINUX
set TF_VAR_server_port=8080	# WINDOWS
terraform plan

plan veya apply komutunu her çalıştırdığınızda komut satırı değişkenlerini hatırlamakla uğraşmak istemiyorsanız, varsayılan bir değer belirleyebilirsiniz:

variable "server_port" {
  description = "The port the server will use for HTTP requests"
  type        = number
  default     = 8080
}

4. Input Variable / Değişken Kullanım Örneği

Terraform kodunuzdaki bir değişkenden gelen değeri kullanmak için, aşağıdaki sözdizimine sahip, değişken referansı adı verilen yeni bir expression türü kullanabilirsiniz:

var.<VARIABLE_NAME>

Örneğin, güvenlik grubunun from_port ve to_port parametrelerini server_port değişkeninin değerine şu şekilde ayarlayabilirsiniz:

resource "aws_security_group" "instance" {
  name = "terraform-example-instance"

  ingress {
    from_port   = var.server_port
    to_port     = var.server_port
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

User Data komut dosyasında bağlantı noktasını ayarlarken aynı değişkeni kullanmak da iyi bir fikirdir. Bir string değişmezinin içinde bir referans kullanmak için, interpolation adı verilen ve aşağıdaki sözdizimine sahip yeni bir expression türü kullanmanız gerekir:

"${...}"

Herhangi bir geçerli referansı küme parantezleri içine koyabilirsiniz. Ardından Terraform onu ​​bir stringe dönüştürecektir. Örneğin, User Data stringinin içinde var.server_port'u şu şekilde kullanabilirsiniz:

user_data = <<-EOF
              #!/bin/bash
              echo "Hello, World" > index.html
              nohup busybox httpd -f -p ${var.server_port} &
              EOF              

5. Output Variable / Değişken Tanımlamak

Input değişkenlerine ek olarak Terraform, aşağıdaki sözdizimini kullanarak output değişkenlerini tanımlamanıza da olanak tanır:

output "<NAME>" {
  value = <VALUE>
  [CONFIG ...]
}

NAME, output değişkeninin adıdır ve VALUE, çıktısını almak istediğiniz herhangi bir Terraform ifadesi olabilir. CONFIG, aşağıdaki isteğe bağlı parametreleri içerebilir:

  • description: Output değişkeninde ne tür verilerin bulunduğunu belgelemek için bu parametreyi kullanmak her zaman iyi bir fikirdir.
  • sensitive: Terraform'a plan veya apply komutları sonunda bu çıktıyı kaydetmemesi talimatını vermek için bu parametreyi true olarak ayarlayın. Bu, çıktı değişkeni parolalar veya özel anahtarlar gibi gizli diziler içeriyorsa kullanışlıdır. Output değişkeniniz, sensitive = true ile işaretlenmiş bir input değişkenine veya kaynak özniteliğine başvuruyorsa, kasıtlı olarak bir secret çıktısı aldığınızı belirtmek için çıktı değişkenini sensitive = true ile işaretlemeniz gerektiğini unutmayın.
  • depends_on: Normalde, Terraform, kodunuzdaki referanslara dayanarak bağımlılık grafiğinizi otomatik olarak bulur, ancak nadir durumlarda, ona ekstra ipuçları vermeniz gerekir. Örneğin, bir sunucunun IP adresini döndüren bir output değişkeniniz olabilir, ancak bu IP'ye, o sunucu için bir güvenlik grubu (güvenlik duvarı) düzgün şekilde yapılandırılana kadar erişilemez. Bu durumda, Terraform'a, depends_on kullanarak IP adresi output değişkeni ile güvenlik grubu kaynağı arasında bir bağımlılık olduğunu açıkça söyleyebilirsiniz.

Örneğin, sunucunuzun IP adresini bulmak için EC2 konsolunda manuel olarak gezinmek yerine, IP adresini bir output değişkeni olarak sağlayabilirsiniz:

output "public_ip" {
  value       = aws_instance.example.public_ip
  description = "The public IP address of the web server"
}

Bu kod yine bir attribute referansı kullanır. Bu sefer aws_instance resoruce'un public_ip attribute'une başvurur. Apply komutunu tekrar çalıştırırsanız, Terraform herhangi bir değişiklik uygulamayacaktır (çünkü hiçbir kaynağı değiştirmediniz), ancak size en sonunda yeni çıktıyı gösterecektir:

$ terraform apply

(...)

aws_security_group.instance: Refreshing state... [id=sg-078ccb4f9533d2c1a]
aws_instance.example: Refreshing state... [id=i-028cad2d4e6bddec6]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

public_ip = "54.174.13.5"

Gördüğünüz gibi, terraform apply'ı çalıştırdıktan sonra, Terraform kodunuzun kullanıcılarının yararlı bulabileceği output değişkenleri konsolda görünür (örneğin, artık web sunucusu deploy edildikten sonra hangi IP'yi test edeceğinizi biliyorsunuz). Herhangi bir değişiklik uygulamadan tüm çıktıları listelemek için terraform output komutunu da kullanabilirsiniz:

$ terraform output
public_ip = "54.174.13.5"

Ayrıca <OUTPUT_NAME> adlı belirli bir çıktının değerini görmek için <OUTPUT_NAME> terraform çıktısını çalıştırabilirsiniz:

$ terraform output public_ip
"54.174.13.5"

Bu, özellikle komut dosyası yazmak için kullanışlıdır. Örneğin, web sunucusunu deploy etmek için terraform apply çalıştıran, public IP'sini almak için terraform public_ip çıktısını kullanan ve dağıtımın çalıştığını doğrulamak için hızlı bir smoke test olarak IP üzerinde curl çalıştıran bir dağıtım komut dosyası oluşturabilirsiniz.