Terraform nedir ? ( Infrastructure as Code nedir ? #2 )
Everything as Code : Infrastructure as Code
Bu yazı Infrastructure as Code nedir? başlıklı bir önceki yazımın devamı niteliğindedir.
Yazının ilerleyen kısımlarında Infrastructure as Code ( IaC ) olarak kısaltılmış bir şekilde kullanılacaktır.
Neden Terraform kullanıyorum/kullanmalıyız?
Vendorların IaC yapabilmenizi sağlayan birbirinden farklı toolları mevcut.
- AWS : CloudFormation
- Azure : Resource Manager
- Google Cloud : Deployment Manager vb.
Diyelim ki şirketinizde geliştirdiğiniz ürünü bu zamana kadar kullanan bütün müşterileriniz Google Cloud Platform üzerinden hizmet alarak kullanıyorlar.Siz de bu sistemin altyapısını DevOps ve IaC kuralları çerçevesinde Google Cloud Deployment Manager ile çok güzel bir şekilde yönetiyorsunuz. Yeni bir müşteri geldi ve mevcut bulut altyapısının AWS üzerinde olduğunu ve ürünü AWS üzerinde kullanmak istediğini söyledi. Burada ya müşteriyi kaybedeceksiniz ya da ürünü AWS’de sunmanın yollarını arayacaksınız. Daha önce Deployment Manager’i deneyimlediğiniz gibi AWS’nin CloudFormation tool’unu öğrenip implementasyonu gerçekleştirebilirsiniz.Fakat her farklı vendor ihtiyacı için o vendora ait IaC tool’unu öğrenmek yerine tek bir multi-vendor özelliğine sahip tool’u öğrenerek bu işi çok daha iyi yapabilirsiniz.
Configuration Managment ve Orchestration farkı
Şimdi gelelim diğer multi-vendor toolları yerine neden Terraform kullandığımıza.
Chef, Puppet, Ansible ve SaltStack gibi toolların tamamı birer Configuration Managment tooludur. Bu mevcut altyapı(sunucularda) yazılımı kurmak ve yönetmek için tasarlandıkları anlamına gelir. Terraform ve CloudFormation ise birer Orchestration tooludur. Bu altyapıyı(sunucuları) oluşturmaları için tasarlanmış anlamına gelir. Bu iki kavramdan birine sahip herhangi bir tool basit olarak birbirinin ihtiyaçlarını karşılayabildikleri için tam olarak birbirinden bağımsız sayılmaz. Ancak Configuration Managment veya Orchestration’a odaklanmak, bazı araçların belirli türdeki görevler için daha iyi bir uyum sağlayacağı anlamına gelir.
Terraform’un bize bu konuda sağladığı en iyi özellik Immutability ve multi-vendor sağlayabilmesidir. Configuration Management kısmı bir kenara sektörde Immutable Infrastructure oluşturma ve Infrastructure Orchestration konusunda bence biçilmez kaftan.
Eğer Terraform gibi multi-vendor özelliğine sahip bir tool ile hem Google Cloud Platform’daki altyapınızı hem de herhangi diğer vendorların altyapısını oluşturan bir sistem tasarlarsanız artık gönül rahatlığı ile farklı vendorlarla ürününüzü sunabilirsiniz.
Terraform nedir ?
Terraform HashiCorp firması tarafından, güvenli ve verimli bir şekilde altyapı oluşturmak, değiştirmek ve iyileştirmek için geliştirilen Open Source bir tooldur.
- Execution Planları
- Aynı altyapıyı birden fazla ortamda oluşturabilmek ( development, staging, production vb. )
- Multivendor desteği ( AWS, Azure, GCP, OpenStack,Wmware etc.) +76
- Immutable Infrastructure
- Resource Grafiği
Terraform ile altyapınızın görsel grafiğini oluşturabilirsiniz.
terraform graph
dediğiniz de dönen sonuç bir Graphviz çıktısıdır.
Bunu import ettiğinizde ise en basit hali ile şöyle bir grafik şeması görürsünüz.
Write, Plan and Create Infrastructure as Code
Terraform’un mottosu.
Altyapıyı oluşturan kodu yazıyoruz, yazdıktan sonra executing planlarımızı görüyoruz ve onayımız sonrası altyapımız oluşturuluyor.
Şimdi aşağıdaki AWS üzerinde basit bir VPC örneğini Terraform ile oluşturalım. Terraform’un dosya uzantısı .tf
dir.
- Write
// vpc.tf// Provider
provider "aws" {
access_key = "XXXXXXXXXXXXXXXXXXXXX"
secret_key = "XXXXXXXXXXXXXXXXXXXXX"
region = "us-east-2"
}// Virtual Private Cloud (VPC)resource "aws_vpc" "default" {
cidr_block = "172.31.0.0/16"
enable_dns_hostnames = true
tags {
Name = "terraform_aws_vpc"
}
}
Görüldüğü gibi hiç Terraform kodu yazmamış olsanız bile kodu anlamamız çok zor olmuyor, oldukça sade ve anlaşılabilir bir yapıya sahip. Bu da Terraform’un IaC deklaratif kod yaklaşımından kaynaklanır. Biz sadece actual state’de ne istediğimizi belirtiyoruz, alt implementasyon ile ilgilenmiyoruz.
enable_dns_hostnames
değeri VPC içerisinde DNS hostname atamasını aktif eder. Bu değer default olarak false
‘dur.
Yukarıda ki kod bloğunda Terraform’un provider olarak AWS’yi kullanmasını ve ilgili credential bilgilerini tanımlıyoruz.
Secret bilgileri açık bir şekilde tanımlamamızı tavsiye ederim. Kendi ortamımda aşağıdaki gibi bir .sh dosyasında tutup her çalışma öncesi source ediyorum.
# credential.shexport AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXsource credential.sh
- Plan
Kodu yazdık, şimdi gelelim Plan kısmına. Kodun bulunduğu klasör içerisinde;
terraform plan
komutu çalıştırdığımızda aşağıdaki çıktıyı alırız.
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.------------------------------------------------------------------------An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ createTerraform will perform the following actions:+ aws_vpc.default
id: <computed>
arn: <computed>
assign_generated_ipv6_cidr_block: "false"
cidr_block: "172.31.0.0/16"
default_network_acl_id: <computed>
default_route_table_id: <computed>
default_security_group_id: <computed>
dhcp_options_id: <computed>
enable_classiclink: <computed>
enable_classiclink_dns_support: <computed>
enable_dns_hostnames: "true"
enable_dns_support: "true"
instance_tenancy: "default"
ipv6_association_id: <computed>
ipv6_cidr_block: <computed>
main_route_table_id: <computed>
tags.%: "1"
tags.Name: "terraform_aws_vpc"Plan: 1 to add, 0 to change, 0 to destroy.------------------------------------------------------------------------Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
Yukarıdaki çıktı da onay öncesi bir önizleme yapılarak, sistemde gerçekleştirilecek işlemler gösterilmektedir.
Terraform’unda belirttiği gibi + create
ile bir VPC resourcenun oluşturulacağını görüyoruz. Detaylı olarak Terraform bütün yapacağı işlemleri bize söylemektedir.Plan: 1 to add, 0 to change, 0 to destroy.
<computed>
yazan değerler AWS tarafından tanımlanacak değer/id bilgisi anlamına gelmektedir, bunun dışındaki değerlerden bazılarını da zaten biz tanımlamıştık, bunları buradan görebiliyoruz.
- Create
Kodu yazdık, sistemde gerçekleşecek işlemleri planladık, şimdi sıra onaylayıp oluşturmakta.
terraform apply
komutunu çalıştırdık ve aşağıdaki çıktı da bizden bir confirm beklemektedir.
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ createTerraform will perform the following actions:+ aws_vpc.default
id: <computed>
arn: <computed>
assign_generated_ipv6_cidr_block: "false"
cidr_block: "172.31.0.0/16"
default_network_acl_id: <computed>
default_route_table_id: <computed>
default_security_group_id: <computed>
dhcp_options_id: <computed>
enable_classiclink: <computed>
enable_classiclink_dns_support: <computed>
enable_dns_hostnames: "true"
enable_dns_support: "true"
instance_tenancy: "default"
ipv6_association_id: <computed>
ipv6_cidr_block: <computed>
main_route_table_id: <computed>
tags.%: "1"
tags.Name: "terraform_aws_vpc"Plan: 1 to add, 0 to change, 0 to destroy.Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.Enter a value:
Buradan anladığımız üzere Terraform her apply işlemi öncesinde default olarak bir terraform plan
işlemi yapmaktadır.yes
diyip, devam ettikten sonra olanlar:
aws_vpc.default: Creating...
arn: "" => "<computed>"
assign_generated_ipv6_cidr_block: "" => "false"
cidr_block: "" => "172.31.0.0/16"
default_network_acl_id: "" => "<computed>"
default_route_table_id: "" => "<computed>"
default_security_group_id: "" => "<computed>"
dhcp_options_id: "" => "<computed>"
enable_classiclink: "" => "<computed>"
enable_classiclink_dns_support: "" => "<computed>"
enable_dns_hostnames: "" => "true"
enable_dns_support: "" => "true"
instance_tenancy: "" => "default"
ipv6_association_id: "" => "<computed>"
ipv6_cidr_block: "" => "<computed>"
main_route_table_id: "" => "<computed>"
tags.%: "" => "1"
tags.Name: "" => "terraform_aws_vpc"
aws_vpc.default: Still creating... (10s elapsed)
aws_vpc.default: Creation complete after 15s (ID: vpc-0fbd16042ce6c4662)Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
AWS Console’dan VPC’lere baktığımız da bir VPC oluşturulduğunu görüyoruz.
Tekrar terraform plan
komutunu çalıştırdığımızda ise aşağıdaki çıktıyı alırız.
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.aws_vpc.default: Refreshing state... (ID: vpc-0fbd16042ce6c4662)------------------------------------------------------------------------No changes. Infrastructure is up-to-date.This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
Terraform burada altyapımız da gerçekleşen bütün işlemleri bir state üzerinde tutmaktadır. Terraform’un in memory olarak default state yapısını kullandığımız için kodun bulunduğu klasör içerisinde terraform.tfstate
dosyası oluşturuldu.
İncelediğimizde :
cat terraform.tfstate
{
"version": 3,
"terraform_version": "0.11.7",
"serial": 1,
"lineage": "f88e8dbc-0f65-8fa7-364e-742cc70c69b6",
"modules": [
{
"path": [
"root"
],
"outputs": {},
"resources": {
"aws_vpc.default": {
"type": "aws_vpc",
"depends_on": [],
"primary": {
"id": "vpc-0fbd16042ce6c4662",
"attributes": {
"arn": "arn:aws:ec2:us-east-2:439438462909:vpc/vpc-0fbd16042ce6c4662",
"assign_generated_ipv6_cidr_block": "false",
"cidr_block": "172.31.0.0/16",
"default_network_acl_id": "acl-0fa210a4ebba72f52",
"default_route_table_id": "rtb-07cc1d56e43bec900",
"default_security_group_id": "sg-0518f7862957b5f16",
"dhcp_options_id": "dopt-0e6e6666",
"enable_dns_hostnames": "true",
"enable_dns_support": "true",
"id": "vpc-0fbd16042ce6c4662",
"instance_tenancy": "default",
"main_route_table_id": "rtb-07cc1d56e43bec900",
"tags.%": "1",
"tags.Name": "terraform_aws_vpc"
},
"meta": {
"schema_version": "1"
},
"tainted": false
},
"deposed": [],
"provider": "provider.aws"
}
},
"depends_on": []
}
]
}
Terraform gerçek ortamda gerçekleştirdiği bütün işlemleri bu state dosyası üzerinde yaşatır ve daima kod üzerindeki actual state’in oluşturulmasını sağlar. Yani siz oluşturduğunuz altyapıyı manuel olarak değiştirseniz bile Terraform state’ini kontrol edip onu eski haline getirecektir. Bu da bize Immutable Infrastructure sağlamaktadır.
Kaynakçalar