developer-guy
Trendyol Tech
Published in
12 min readJan 24, 2020

--

Terraform

Trendyol’da biz bireysel gelişimimize önem verdiğimiz kadar ekip olarak da gelişmeye önem veriyoruz dolayısıyla bireysel olarak kendimize katmaya çalıştığımız yeni teknolojiler olsun yeni yaklaşım ve patternler olsun bunları ekibe yaydığımız zaman aslında başarılı olmuş oluyoruz.Şirket kültürümüz de bizi mümkün olduğunca OpenSource dünyaya katkı sunmaya doğru teşvik ediyor, gerek Github’da geliştirdiğimiz OpenSource projelerimizle gerekse Medium’ daki yazılarımızla biz de pratiklerimizi öğrendiklerimizi aktarmaya çalışıyoruz.Daha sonraki yazılarımızda Terraform’u nerelerde ne nasıl kullandığımızla ilgili aktarımlar da yapacağımız fakat önce Terraform’u anlamak adına HashiCorp’un Terraform tutorialını temel alan ve Türkçe olarak baştan sonra özetini çıkardığımız Terraform özetini paylaşmak istedik.

Infrastructure as Code

• Resource’ları manual olarak kullanıcı arayüzlerinden konfigüre etmek yerine tanım dosyası veya dosyaları (definition files — desired state) kullanarak infrastructure’ımızı yönetmemizi sağlayan bir işlemdir.Bu örnekte Resource belirli bir ortamdaki herhangi bir altyapının parçasıdır.Örneğin vm,security group,network interface.

Terraform Nedir ?

Terraform HashiCorp firması tarafından sunulan infrastructure as code tooludur.Güvenli ve verimli bir şekilde infrastructurelarımızı oluşturmak , değiştirmek ve versiyonlamak için kullanılır.

Workflow(Akış)

• Scope » Belirli bir proje için hangi kaynakların oluşturulması gerektiğini belirle.

• Author » Scope parametrelerine göre HCL tabanlı konfigürasyon dosyanı oluştur.

• Initialize » Konfigürasyon dosyalarının bulunduğu proje klasöründe “terraform init“ komutunu çalıştır, bu komut proje için doğru olan provider pluginlerini indirecektir.

• Plan & Apply » “terraform apply“ komutunu çalıştırarak infranın oluşturulma sürecini onayla , bu adımda Terraform oluşturmak istediğimiz (desired state) inframızı gerçekleyebilmek için alacağı aksiyonları gösterir ve bizden onay bekler onayı aldıktan sonra “terraform apply“ komutu ile gerçek resource’larımızı ve state dosyamızı oluşturur , state dosyamız konfigurasyon dosyamızdaki değişiklikler ile mevcut infra durumumuzu karşılaştırmak amacıyla kullanılır.

Advantages of Terraform

• Platform Agnostic
» Modern Datacenterlar çeşitli uygulamalarımızı desteklemek için bir veya birkaç farklı cloud ve platform’a sahip olabiliriz. Terraform ile beraber uygulamanın veya organizasyonun ihtiyaçlarına uygun bir şekilde yazacağın konfigürasyon dosyası(HCL) tarafından aynı workflow(akış) ile ortamını yönetebilirsin.

• State Management
» Terraform proje ilk oluşturulduğu anda bir state dosyası oluşturur.Bu state dosyasını infra üzerinde plan ve değişiklikler yapmak için kullanır. Terraform herhangi bir komut(operation)dan önce state’i mevcut infra durumuyla güncellemek için refresh çalıştırır.Konfigürasyonda bir değişiklik yapılırsa veya bir kaynak eklenirse, Terraform, hangi değişikliklerin yeni bir kaynak veya kaynak değişikliği ile sonuçlandığını belirlemek için bu değişiklikleri durum dosyasıyla karşılaştırır.

• Operator Confidence

» Terraform infra üzerinde bozulmaları sebebiyet vermemek için alacağı aksiyonları öncesinde kullanıcıya gösterir ve onay bekler.

Build Infrastructure

• Terraformda infrayı tanımlamak için kullanılan dosyalar “Terraform Configuration“ dosyaları olarak bilinir.(“.tf“ uzantılı dosyalar.)Kısaca bu JSON’dan türetilmiş dile “HCL“‘de denilir yani HashiCorp Configuration Language.

Providers

» Provider = hizmet sağlayıcı (servis sağlayıcı)
» Resource = hizmet(servis)

provider “aws“ { 
profile = “default“ » macOS’daki .aws/credentials dosyasındaki profil ismi, bu sayede terraformun sensitive dataya da nasıl eriştiğini de görüyoruz.
region = “us-east-1“
}

provider “datadog“ {
api_key = var.datadog_api_key
app_key = var.datadog_app_key
}


resource “aws_instance“ “example“ {
ami = “ami-2757f631“
instance_type = “t2.micro“
}
resource “datadog_monitor“ “example“ {
name = “Instance Example“
type = “metric alert“
}

• “Provider Block” Provider’ın ismini ve ayarlarını konfigüre etmek için kullanılır.Provider’ın görevi Resourceları oluşturmak ve yönetmektir.Provider aslında Terraformun resource ile olan API etkileşimlerini yönetmek için kullandığı bir plugindir yani ne yapar , bizim için API etkileşimlerini anlayarak Resource’ları oluşturur.Tek Terraform Configuration dosyasında bir çok Provider Blok yer alabilir.

Resources

• “Resource Block” ise Provider’ın sağladığı infrastructure içerisindeki mevcut bir resource’u ifade eder(servisi), Resource fiziksel bir component olabileceği gibi örneğin EC2 instance, mantıksal bir kaynak da olabilir Heroku uygulaması gibi.

• “Resource Block” tanımı 2 text parçasından oluşur.

» “aws_instance“ Resource’un tipidir, buradaki prefix(“aws_“) Resource’u Provider’ı ile mapler,yani Resource’un hangi provider tarafından yönetildiğini Terraform’a söyler.Bu örnekte prefix “aws_“ olduğu için Resource’un AWS Provider ‘ı tarafından yönetildiğini Terraform anlayabiliyor.

» “example“ ise Resource’un ismidir.

Resource Block içerisinde de yine Provider Blok olduğu gibi Resource ayarları yapılır.

Initialization

• Yeni bir Terraform konfigürasyonuna başlamak için (yani infrayı tanımlamaya başlamak için) çalıştırılması gereken ilk komut ;
terraform init“ komutudur , bu komut sonraki komutlarda kullanılacak olan lokal ayarları ve datayı hazırlar.Aynı zamanda konfigürasyon dosyamızda kullanılan Provider’ın binary datasını indirir ve yükler.(bu binary sayeside provider altında tanımlı olanları Resource’ların yönetimi gerçekleştirilir, genelde REST api üzerinden iletişim kurulur.) Bu komutun çıktısında pluginin hangi versiyonunun kurulduğunu belirtir.

Format and Validate Configurations

» terraform fmt
» terraform validate

Apply Changes

• “terraform apply“ komutu bizim için “execution plan“‘ı gösterir, terraform 0.11 versiyon öncesi bu execution plan için ayrıca “terraform plan“ çalıştırmamız gerekiyordu.Bu “execution plan“ asıl olan infra ile(actual state) HCL dosyasında belirtilen konfigürasyonla(desired state) eşleyebilmek için sırasıyla -burada sıra kelimesi önemli çünkü Terraform ilgili Resource’ları hangi sırada oluşturacağını konfigürasyon tanımları içerisindeki “dependency cycle“‘a bakarak anlar- Terraform’un hangi aksiyonları alacağını tanımlar.

• “+“ işareti Terraform, Resource’u oluşturacak demek, ayrıca setlenecek attributeleri(field,özellik) de listeler,(buradaki attribute mantığı ilgili Resource’umuzun alabileceği konfigürasyon değerleri demek.)

• “known after apply“ resource oluşturulmadan bilinemeyecek değerler için kullanılır.

• Plan başarıyla oluşturulduğunda Terraform senin onayını bekler çünkü eğer planda istemediğin bir durum veya riskli olduğunu düşündüğün bir durum varsa işlemi iptal edebilirsin eğer herhangi bir sorun yoksa “yes“ diyerek işlemi devam ettirebilirsin.(-auto-approve flag özelliği ile otomatik onaylı olarak bu işlemi gerçekleştirebiliriz)

• Terraform aynı zamanda “terraform.tfstate“ adlı bir dosya tutar ve bu dosyaya bazı datalar yazar, bu dosya son derece önemlidir çünkü Terraform oluşturduğu Resource’ların bilgilerini bu dosyada tutar bu sayede Terraform neyi yönettiğini bilir ve biz de bu sayede ne kaynaklarımız olduğunu bilebiliriz, bu dosya kaydedilip daha sonra aynı infrayı oluşturmak isteyen birisi ile paylaşılabilir, zaten Terraform ile çalışırken de state’i otomatik olarak paylaşmak için “setup remote state“ mantığı önerilir.

» “terraform show“ komutu ile hangi mevcut durumda olduğumuzu (actual state) gözlemleyebiliriz.

» Manual state yönetimi için “terraform state“ komutuna bakabiliriz.

• Bizim bu konfigürasyonda çalıştırdığımız EC2 örneği statik olarak verilen bir AMI(Amazon Machine Image)’a dayanıyor fakat bu AMI’ya herhangi ekstra bir yazılım yüklü değil eğer image-based (imaj tabanlı) bir infra istiyorsan bu bizim için yeterli.(“HashiCorp Packer“ kullanarak machine imajlar oluşturabiliriz) fakat çoğu infra bazı özelleştirmelere ihtiyaç duyabilir bunu da Terraform’un “provisioning“ ile çözebiliriz. Shell, Ansible, Puppet,. Chef vs. gibi provisionerlar Terraform tarafından desteklenir.

Change Infrastructure

Day 1 Challenge → Nothing to Something
Day 2+N Challenge → Continue to evolving

• İnşa ettiğimiz infralarımız sürekli olarak gelişmektedir, Terraform bu değişimleri yönetmeye yardımcı olmak için inşa edilmiştir. Terraform, konfigürasyonlarını değiştirdiğin zaman arzu edilen duruma(desired state) ulaşmak için execution planı oluştururken sadece gerekli olan Resource’ları değiştirir(optimistic update), bunu yaparken de söylediğimiz gibi state dosyamızdan faydalanır.

Configuration

• Örneğin “aws_instance“ Resourcemuzdaki “ami attributesini“ değiştirdik diyelim ardından tekrar “terraform apply“ yaptığımızda Terraform bu değişikliği mevcut kaynaklar üzerine uygular.

•Ardından “-/+“ işaretlerini görüyoruz bu şu demek oluyor Terraform Resource’u update etmek yerine destroy edip ardından recreate edecek.
~“ işareti gördüklerimiz ise update edilebilir demek, yani dolayısıyla “ami“ attribute’ü(özelliği) değiştirmek Resource’umuzun yeniden oluşturulmasını gerektirdiğini anlıyoruz.

• Aslında buradaki update sürecindeki yapılacak olan tüm işlemleri
Terraform bizim için halledecektir ve plan sayesinde de yapacağı aksiyonları bize gösterir.

» Resources: 1 added, 0 changed, 1 destroyed

Destroy Infrastructure

• Resource’lar “terraform destroy“ komutuyla beraber destroy edilebilir. Buradaki destroy sanki konfigürasyon dosyasından tüm Resource’lar silinmiş gibi düşünerek “terraform apply“ gibi davranır.

• “-“ işareti Resource’un destroy edileceği anlamına gelir.“terraform destroy“ komutunda da execution plan gösterilir ve kullanıcıdan onay beklenir, aynı “terraform apply“ komutu gibi Terraform’da hangi Resource’ların hangi sırada destroy edileceğine karar verir eğer konfigürasyonda tek resource (kaynak) varsa sıranın bir anlamı olmayabilir fakat daha karmaşık senaryolarda “destroy“ komutu uygun sırada Resource’ları destroy edecektir.

Resource Dependencies

• Buraya kadarki örneklerimizde hep tek bir Resource tanımı ile çalıştık fakat gerçek bir infra bir çok farklı kaynaklara sahiptir.
Terraform konfigürasyonlarına da bir çok kaynak tanımı yapılabilir.

Assigning an Elastic IP

resource “aws_eip“ “ip“ { 
vpc = true
instance = aws_instance.example.id
}

• Daha önce EC2 resource örneğimizle benzer gözüküyor fakat bu sefer “aws_eip“ Resource’u oluşturuyoruz bu resource bir Elastik IP tahsis ediyor ve EC2 instance’ı ile bunu ilişkilendiriyor.

• “aws_eip“ Resource’u tek parametresi EC2 instance’ına IP atayabileceğin “instance“ atrribute’üdür. Bu değer için biz EC2 instance’ından bir attribute referesans olarak alıp kullanabilmek için “interpolation“ adı verilen bir özellik kullanıyoruz.

• “interpolation“ yapısı çok basit bu örnekte biz “aws_instance.example“ Resource’umuzdan “id“ attribute’ü talep ediyoruz.

Bu örnekteki aws_eip’ ye geçilen aws_instance’inin id’si Terraform’a dependency konusunda çıkarım yapmasında yardımcı oluyor yani aws_eip Resource’u oluşturulmadan önce aws_instance’ı oluşturulması gerektiğini bu cycle sayesinde anlayabiliyor Terraform.

Implicit and Explicit Dependencies (Kapalı & Açık)

• Terraform “interpolation“ ifadelerinde kullanılan Resource attribute’lerine bakarak otomatik olarak bir Resource’un diğerine depend ettiğini (bağlı olduğunu) anlayabilir.Yukarıdaki örnekteki “aws_instance.example.id“‘deki referans “example“ adındaki “aws_instance“ üzerinde bir “implicit dependency“ oluşturur.

• Terraform bu dependency bilgisini farklı kaynakların oluşturulmasındaki doğru sıraya karar vermek için kullanır.Yukarıdaki örnekte Terraform “aws_instance“‘ının “aws_eip“‘den önce oluşturulması gerektiğini biliyor.

• Fakat bazen bu Resource’lar arası dependencyler Terraform’a görünür olmayabilir.

Herhangi bir Resource tarafından verilen “depends_on“ argümanı “explicit dependencies“ oluşturmak için Resource listesini parametre olarak alır.

örneğin » depends_on = [aws_s3_bucket.example]

• Fakat her Resource bir dependencye sahip olmak zorunda değil “Non-Dependent Resources“ olarak adlandırılan bu Resource’lar Terraform tarafından paralel olarak oluşturulmaya çalışılır.

Provisioners

• Eğer image tabanlı bir infra üzerinde çalışacaksak -yani statik machine image id ile bu örnekte “ami-b374d5a5“- buraya kadar öğrendiklerimiz bizim için yeterli olabilir fakat makinelerimiz üzerinde bazı initial kurulumlara veya özelleştirmelere ihtiyaç duyduğumuz durumlarda “provisioners“ diye tabir edilen toollar bizim scriptler çalıştırmamıza, dosyalar yüklememize vs yardımcı olabilir.

resource “aws_instance“ “example“ { 
ami = “ami-b374d5a5“
instance_type = “t2.micro“
provisioner “local-exec“ {
command = “echo ${aws_instance.example.public_ip} > ip_address.txt“
}
}

• Burada dikkat etmemiz gereken “provisioner block“‘tur, bir Resource altına birden fazla bu şekilde “provisioner block“ ekleyebiliriz.Buradaki örnekte provisioner olarak “local-exec“ kullanıyoruz.“local-exec“ Provisioner’ın amacı Terraform’u çalıştırdığın makinede üzerinde komutları çalıştırmaktır.

• Bir diğer kullanışlı olan provisioner ise “remote-exec“‘dir.Bu da ilgili Resource oluşturulduğunda Resource üzerinde remote olarak çalıştırılacak scriptler için kullanılır.“remote-exec“ kullanmak amacıyla öncelikle “connection block“ içerisinde “ssh“ mı “winrm“ connection’ı mı kullanacağımızı belirtmemiz gerekiyor.

resource “aws_key_pair“ “example“ { 
key_name = “examplekey“
public_key = file(“~/.ssh/id_rsa.pub“)
}
resource “aws_instance“ “web“ {
key_name = aws_key_pair.example.key_name
connection {
type = “ssh“
user = “root“
private_key = file(“~/.ssh/id_rsa“)
host = self.ip
}

provisioner “remote-exec“ {
inline = [
“sudo amazon-linux-extras enable nginx1.12“,
“sudo yum -y install nginx“,
“sudo systemctl start nginx“
]
}

• Şimdi buradaki adımları biraz açıklamak gerekirse ; “aws_instance“ Resource’umuza ssh connection kurabilmemiz için bir keypaire ihtiyacımız var . “aws_key_pair“ Resource’umuz da bizim için lokalimizden oluşturduğumuz keypair’lerimizi AWS’e yükleyebilmemizi sağlar.Daha sonra da “aws_instance” Resource’umuzun “key_name” attribute’ü sayesinde bu “keypair“‘i kullanması gerektiğini söylüyoruz.“aws_instance“ resource’umuz içerisinde de connection kurabilmemiz için gerekli attributeleri veriyoruz.Burada “self“ kelimesine bir parantez açmak istiyorum, connection bloğu içerisindeki ifadeler parent resource’a ismini kullanarak değil bu özel keyword olan “self“ sayesinde ulaşırlar yani bu örnekte aslında “self.ip“ diyerek “web“ adlı “aws_instance“ resource’umuzun “ip“ attribute’üne erişiyoruz.

Running Provisioners

• Unutmamak gerekir ki provisionerlar ilgili resource oluşturulduğunda çalıştırılır dolayısıyla zaten çalışan bir makinenin yazılımını değiştiremezler veya konfigürasyon yönetimi yerine geçemezler.Aslında sadece bir makineye ön yükleme adımını gerçekleştirirler.

Failed Provisioners and Tainted Resources

• Eğer resource başarılı bir şekilde oluşturulup bu provisioning adımında başarısız olursa Terraform hata verir ve bu resource’u “tainted“ olarak işaretler.Bu da şu demek oluyor “tainted“ olarak işaretli resource fiziksel olarak oluşturulmuş fakat kullanım için güvenli değil.Buradaki bir diğer önemli konulardan birisi bir sonraki “plan“ oluşturulduğunda -yani yeniden apply komutu çalıştırıldığında- Terraform aynı “provisioning“ adımını resource üzerinde yeniden çalıştırmak yerine -çünkü bu resource’un güvenli olduğunun garantisi yok- “tainted“ olarak işaretli tüm bu resource’ları siler yerine yenilerini oluşturur ve oluşturduktan sonra da bu “provisioning“ adımını gerçekleştirmeye çalışır.

Manually Tainting Resources

• Terraform CLI(command line interface) üzerinde desteklediği “taint“ komutuna sahiptir, bu komut infrayı güncellemek yerine sadece state dosyamızı günceller ve resource’u “tainted“ olarak işaretler dolayısıyla bir sonraki “plan“ bize bu resource’un silinip yeniden oluşturulacağını gösterecektir.

• Manuel olarak bir resource “tainted“ olarak işaretlemek için çalıştırılması gereken komut:

» terraform taint resource.id

• “resource.id“ ne demek oluyor dersek eğer aslında resource’umuzun ismidir diyebiliriz yani yukarıdaki tanımdan örnek verecek olursak “resource.id“ “aws_instance.web“ olacaktır.

Destroy Provisioners

• Provisioners sadece makinenin ön yüklenmesinde devreye girmek yerine makine kapatılırken de devreye girebilir.Bu durum bize sistemin temizlenmesi gibi graceful olarak makinenin kapanması konusunda destek sağlayabilir.

Input Variables

• Biz bu .tf dosyalarımızı tamamiyle paylaşılabilir ve versiyon kontrol sistemine entegre edebilmemiz için kullandığımız konfigürasyonları parametreleri kullanacak şekilde ayarlamalıyız çünkü şuan halen access_key ve secret_key’lerimizi açık olarak yazıyoruz.

• Örnek olarak “region“ değerimizi değişkenden okuyacak şekilde güncelleyelim.Değişkenlerimizi nerede tutacağız konusundaki önerilen yöntem ayrı bir “variables.tf“ adlı dosya oluşturmak fakat bu herhangi bir dosyada olabilir çünkü Terraform proje klasörü altındaki tüm .tf dosyalarını yükler.

variable “region“ { 
default = “us-east-1“
}

» Buradaki bir diğer güzellik de burada default değer verdiğimiz değişkenimiz aslında optional yani Terraform tarafından zorunlu olarak kabul edilmeyen bir değişken oluyor yani eğer default keywordünü kullanmasaydık Terraform bu değişkenin kullanıcı tarafından verilmesini zorunlu hale getirecekti.

• Peki konfigürasyon dosyamız içerisinde bu değişkene nasıl referans edeceğiz ? Çok basit :

provider “aws“ { 
region = var.region
}

• Terraform değişkenlere erişim olarak “var“ özel keywordünü kullanır.

Assigning Variables

• Terraform’da değişken atamanın bir çok yolu var.

» Command-line flags
• “-var“ flag sayesinde CLI üzerinden değişken atayabilirsin.(apply,plan ve refresh komutları bu flag’i kabul eder)

» terraform apply -var ‘region=us-east-2’

» From a File
• Terraform tarafından “terraform.tfvars“ or “*.auto.tfvars“ ile eşleşen dosyalar otomatik olarak yüklenip değişkenleri doldurmak için kullanılır , örneğin “terraform.tfvars“ adında bir dosya oluşturup içeriğini basitçe key/value şeklinde “region=us-east-2“ doldurabiliriz.Bu dosya isimlendirmeleri için otomatik olduğunu söyledik fakat başka bir isimde dosya kullandığımızda CLI üzerinden bu dosyayı belirtmemiz gerekecektir bunuda “-var-file“ flag’i ile yaparız.

» terraform apply -var-file=“secret.tfvars“

» From environment variables
• Terraform değişkenlerin değerini bulabilmek için TF_VAR_name formundaki environment variableları okur.Örneğin TF_VAR_region değişkeni region değişkenine setlenecektir.Fakat burada bir kısıtlama var o da şudur bu tip environment variable’lar sadece string(text) tipindeki değişkenleri doldurabilir.

Variable Types

• Lists
» variable “cidrs“ { default = [] }
» variable “cidrs“ { type = “list“ }
» terraform.tfvars dosyasında ise cidrs = [ “10.0.0.0/16“, “10.1.0.0/16“ ]

• Maps
Bu tip değişkenlere aslında AMI’ler iyi bir örnek olabilir neden ? Çünkü AMI’lar kullanılan region’a özgüdür.Dolayısıyla Maps kullanarak bu region’lara özgü AMI değerlerini tanımlayabiliriz.

variable “amis“ {
type = “map“
default = {
“us-east-1“ = “ami-b374d5a5“
“us-west-2“ = “ami-4b32be2b“
}
}

ve bu tanımlamayı aws_instance resource’umuzun “ami“ attribute’ünde şu şekilde kullanabiliriz :

» ami = var.amis[var.region]

Diğer Maps atama örnekleri :

» terraform apply -var ‘amis={ us-east-1 = “foo“, us-west-2 = “bar“ }’
» variables “amis“ { type = “map“ }
» terraform.tfvars dosyasında
amis = {
“us-east-1“ = “ami-abc123“
“us-west-2“ = “ami-def456“
}

Output Variables

• “Outputs“ Terraform’a hangi datanın önemli olduğunu söylemenin yoludur yani Terraform senin resource’ların için belki yüzlerce belki binlerce attribute tutabilir sen bu attributelerden sadece bir kaçı ile ilgileniyor olabilirsin.
Data “apply“ komutunun çağrıldığında çıktı olarak verilir ve “output“ komutu ile de sorgulanabilir.

Defining Outputs

• Örnek olarak bir output tanımlayalım ve bu bizim oluşturmuş olduğumuz Elastic IP adresimizin public IP adresini output olarak versin.Bu tanımı .tf dosyalarından birine ekleyebilirsin.

output “ip” {
value = aws_eip.ip.public_ip
}

Viewing Outputs

• Output tanımı yapıldıktan sonra “apply” komutunu çalıştırdığımızda bu değerin çıktı olarak console yazıldığını görebiliriz fakat istersen “apply” işlemi bittikten sonra da output değişkenleri “output” komutu ile sorgulayabilirsin.

» terraform output ip

Modules

• Terraformda Modüller bir grup olarak yönetilen Terraform konfigurasyonlarının kendine yetebilen(self-contained) paketleridir.Buradaki kendine yetebilenden kasıt şudur Modüller de aslında HCL ile yazılmış tıpki bizim konfigurasyonlarımız gibi bir inputları ve outputları olan tanım dosyalarını içeriyor dolayısıyla Modüller de dolayısıyla bir infrayı ifade edebilir tek başlarına.Ama asıl amaçlı tekrardan kullanılabilir componentler sağlamaktır (reusable components) yani biz Modüllere bir input veririz ve o bizden gerçeklediği complexityi gizler ve bir output verir yani infranın kara kutuları gibi davranır.

Using Modules

• Terraform Registry (https://registry.terraform.io/) bizim için kullanıma hazır Modüller sunar.

terraform {
required_version = “0.11.11”
}
provider “aws” {
access_key = “AWS ACCESS KEY”
secret_key = “AWS SECRET KEY”
region = “us-east-1”
}
module “consul” {
source = “hashicorp/consul/aws”
num_servers = “3”
version = “0.7.3”
}

» Bu örnekte bize bir Consul cluster’ı sağlayacak olan Consul Terraform Module’ü kullanıyoruz.Burada “source” attribute’ü bize ilgili modülün nereden getirileceğini söyler.Bu örnekte Terraform Registry’den ilgili modül bizim için indirilecektir.Ayrıca Terraform modülleri çeşitli kaynaklardan da indirilebilir örneğin Git, Mercurial, HTTP, ve local dosyalar.

» Modülümüz için zorunlu olan tek attribute “source” attribute’dür onun dışındaki değerler aslında bizim modülümüz için tanımladığımız ve modülümüz içerisinde kullandığımız input değerleridir.

• Modül tanımımızı yaptıktan sonra “init” komutunu çalıştırmamız gerekiyor ki ilgili modül bizim için indirilebilsin.
• Fakat “init” komutu modüllerin yeni versiyonlarının kontrolünü yapmaz fakat “-upgrade” flag’i ile kullanırsak modüllerimizi yeni versiyonlarıyla güncelleyecektir.
• Modüller ile çalışırken dışarıdan version değerini vermek bizim için önerilir.

Module Outputs

• Modüllerimizin output değerleri olabileceğini söylemiştik.Peki bu örneğimizde kullandığımız “Consul Terraform Module” bizim için ne çıktıları veriyor öğrenmek istersek https://registry.terraform.io/modules/hashicorp/consul/aws?tab=outputs adresine gidebiliriz.Peki bu output değerine konfigürasyonlarımızdan (.tf dosyalarımız) nasıl referans ederiz ?

» Sentaks çok basit aslında : ${module.NAME.OUTPUT}

Remote State Storage

• Şimdi buraya kadar infranı lokal makinemiz üzerinden inşa ettik , değiştirdik ve sildik.Aslında bu test ve development ortamlarımız için kabul edilebilir fakat iş production ortamına geldiği noktada önerilen bu state dosyasınını lokal makinemizden ayrı bir yerde yönetilmesidir.Bunu yapmanın en iyi yolu da Terraform’u state dosyasına paylaşılan erişime sahip remote bir environment ile çalışmaktır.

• Terraform “remote backends” adını verdiği bir feature sayesinde takım tabanlı workflowları destekler.Aslında bu “remote backend” olarak adlandırdığımız yapılar Terraform’un state dosyamız için paylaşılan bir depo kaynağı kullanmasını sağlar. Terraform bir çok backend seçeneceğini destekler fakat HashiCorp tarafından önerilen backend tipi Terraform Cloud’dur. Terraform Cloud’un bizim için sağladığı avantajlara ilgili linkten bakılabilir.
https://learn.hashicorp.com/terraform/cloud/tf_cloud_gettingstarted.html

• Basit bir örnekle Terraform Cloud’u remote backend olarak nasıl kullanabileceğimizi gösterelim.

terraform { 
backend “remote” {
organization = “<ORG_NAME>”
workspaces {
name = “Example-Workspace”
}
}
}

Teşekkürler..

--

--

developer-guy
Trendyol Tech

🇹🇷KCD Turkey Organizer🎖Best Sigstore Evangelist🐦SSCS Twitter Community Admin✍️@chainguard_dev Fan📦Container Addict📅Organizer at @cloudnativetr•@devopstr