Kodėl visi kalba apie Terraform ir kas tai iš viso yra?
Jei dirbate IT srityje, tikriausiai pastebėjote, kad pastaraisiais metais Terraform tapo beveik tokiu pat populiariu žodžiu kaip „cloud” ar „DevOps”. Bet kas tai iš tikrųjų? Paprasčiausiai tariant, Terraform yra įrankis, leidžiantis aprašyti visą jūsų infrastruktūrą kodu. Skamba abstrakčiai? Įsivaizduokite, kad vietoj to, jog rankiniu būdu AWS konsolėje spaudytumėte mygtukus kurdami serverius, duomenų bazes ir tinklus, galite tiesiog parašyti tekstinį failą, kuris viską padaro už jus.
HashiCorp sukurtas Terraform naudoja deklaratyvų požiūrį – jūs aprašote, kokią infrastruktūrą norite turėti, o ne kaip ją sukurti. Tai fundamentalus skirtumas nuo tradicinių skriptų. Jums nereikia galvoti apie visus žingsnius ir sąlygas – tiesiog pasakote „noriu 3 serverių su tokiomis specifikacijomis” ir Terraform išsiaiškina, kaip tai pasiekti.
Kas dar svarbiau, Terraform palaiko daugybę debesų platformų ir paslaugų teikėjų – AWS, Azure, Google Cloud, DigitalOcean, net Cloudflare ar GitHub. Tai reiškia, kad išmokę vieną įrankį, galite valdyti praktiškai bet kokią infrastruktūrą. Tai kaip mokėti anglų kalbą ir galėti bendrauti daugelyje pasaulio šalių, o ne mokėti atskirą kalbą kiekvienai šaliai.
Infrastruktūra kaip kodas – ne tik madinga frazė
Infrastructure as Code (IaC) koncepcija skamba kaip dar vienas buzzword’as, kurį marketingo žmonės išgalvojo, kad parduotų daugiau produktų. Bet iš tikrųjų tai vienas iš reikšmingiausių poslinkių, kaip valdome IT sistemas. Pagalvokite, kaip anksčiau atrodė serverio kūrimas: kažkas turėjo prisijungti prie konsolės, rankiniu būdu sukonfigūruoti visus parametrus, galbūt užsirašyti, ką padarė (arba neužsirašyti), o tada tikėtis, kad kitą kartą prisimins, kaip tai padarė.
Su Terraform visa jūsų infrastruktūra tampa tekstu. Tekstą galite saugoti Git repozitorijoje, galite daryti code review, galite matyti istoriją, kas ir kada pakeitė. Jei kažkas sugenda, galite grįžti prie ankstesnės versijos. Tai tas pats kaip programavimas, tik vietoj aplikacijos kodo rašote infrastruktūros kodą.
Praktinis pavyzdys: įsivaizduokite, kad jūsų projektas auga ir reikia sukurti naują aplinką testavimui. Be Terraform tai reikštų valandas ar net dienas darbo, kopijuojant konfigūracijas, tikrinant, ar viskas sukurta teisingai. Su Terraform? Tiesiog nukopijuojate konfigūraciją, pakeičiate kelis parametrus ir paleidžiate `terraform apply`. Per kelias minutes turite identišką aplinką.
Kaip pradėti naudoti Terraform praktiškai
Gerai, teorija skamba puikiai, bet kaip iš tikrųjų pradėti? Pirmas žingsnis – įsidiegti Terraform. Tai paprasta: atsisiųskite binary failą iš oficialios svetainės arba naudokite paketų valdymo įrankius kaip Homebrew, Chocolatey ar apt. Įdiegę patikrinkite su `terraform –version` – jei matote versijos numerį, esate pasiruošę.
Dabar sukurkite naują direktoriją savo projektui ir joje sukurkite failą pavadinimu `main.tf`. Tai bus jūsų pirmasis Terraform failas. Štai paprastas AWS EC2 instancijos pavyzdys:
provider "aws" {
region = "eu-west-1"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "Mano-Pirmas-Serveris"
}
}
Šis kodas sako: naudok AWS providerį Airijos regione ir sukurk EC2 instanciją su konkrečiu AMI ir tipo t2.micro. Paprasta, tiesa? Bet prieš paleisdami, turite sukonfigūruoti AWS kredencialus. Paprasčiausias būdas – naudoti AWS CLI ir paleisti `aws configure`, arba tiesiog nustatyti aplinkos kintamuosius.
Kai viskas paruošta, paleiskite tris pagrindines komandas:
1. `terraform init` – inicializuoja projektą, atsisiunčia reikalingus providerius
2. `terraform plan` – parodo, ką Terraform planuoja padaryti (VISADA paleiskite prieš apply!)
3. `terraform apply` – iš tikrųjų sukuria infrastruktūrą
Po `terraform apply` pamatysite planą ir Terraform paklaus patvirtinimo. Įveskite „yes” ir stebėkite, kaip jūsų infrastruktūra kuriama realiuoju laiku.
State failas – Terraform širdis ir siela
Dabar pasikalbėkime apie vieną iš svarbiausių Terraform dalių, kurią daugelis pradedančiųjų ignoruoja, kol nesusiduria su problemomis – state failą. Kai paleidžiate `terraform apply`, Terraform sukuria failą pavadinimu `terraform.tfstate`. Šiame faile saugoma visa informacija apie jūsų esamą infrastruktūrą.
Kodėl tai svarbu? Nes Terraform turi žinoti, kas jau egzistuoja, kad galėtų nustatyti, ką reikia sukurti, pakeisti ar ištrinti. Be state failo Terraform būtų aklas – nežinotų, ar tas serveris jau sukurtas, ar dar ne. State failas yra kaip žemėlapis, rodantis, kur esate dabar.
Bet čia yra problema: jei dirbate komandoje, negalite tiesiog laikyti šio failo savo kompiuteryje. Kas nutiks, jei kolega bandys paleisti Terraform su savo kompiuterio state failu? Katastrofa. Todėl state failą reikia laikyti bendrojoje vietoje – remote backend’e.
Populiariausi variantai:
– S3 bucket su DynamoDB (AWS) – klasikinis pasirinkimas, DynamoDB naudojamas state locking’ui
– Azure Storage Account – jei naudojate Azure
– Terraform Cloud – oficialus HashiCorp sprendimas, nemokamas mažoms komandoms
– Google Cloud Storage – GCP vartotojams
Remote backend konfigūracija atrodo taip:
terraform {
backend "s3" {
bucket = "mano-terraform-state"
key = "production/terraform.tfstate"
region = "eu-west-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
Svarbu: NIEKADA necommitinkite state failo į Git. Jame yra jautrios informacijos, įskaitant slaptažodžius ir API raktus. Pridėkite `*.tfstate*` į `.gitignore` failą.
Moduliai – kaip išvengti kodo dubliavimo
Kai pradėsite kurti sudėtingesnes infrastruktūras, greitai pastebėsite, kad kartojate tą patį kodą. Pavyzdžiui, jums reikia sukurti kelis panašius serverius skirtingose aplinkose, arba kiekvienas projektas naudoja panašią VPC konfigūraciją. Čia į pagalbą ateina moduliai.
Terraform moduliai yra kaip funkcijos programavime – jūs apibrėžiate pakartotinai naudojamą infrastruktūros dalį su parametrais (variables) ir galite ją naudoti kiek norite kartų su skirtingais parametrais. Modulis gali būti toks paprastas kaip vienas serveris arba toks sudėtingas kaip visa mikroservisų architektūra.
Sukurkime paprastą modulį serverio kūrimui. Sukurkite direktoriją `modules/web-server/` ir joje `main.tf`:
variable "server_name" {
description = "Serverio pavadinimas"
type = string
}
variable "instance_type" {
description = "EC2 instance tipas"
type = string
default = "t2.micro"
}
resource "aws_instance" "server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type
tags = {
Name = var.server_name
}
}
output "server_ip" {
value = aws_instance.server.public_ip
}
Dabar galite naudoti šį modulį savo pagrindiniame kode:
module "production_server" {
source = "./modules/web-server"
server_name = "prod-web-01"
instance_type = "t2.medium"
}
module "staging_server" {
source = "./modules/web-server"
server_name = "staging-web-01"
}
Matote, kaip tas pats kodas pakartotinai naudojamas su skirtingais parametrais? Tai taupo ne tik laiką, bet ir sumažina klaidų tikimybę. Dar geriau – galite dalintis moduliais su komanda ar net viešai per Terraform Registry.
Workspace’ai ir aplinkų valdymas
Kiekvienas projektas turi bent kelias aplinkas – development, staging, production. Kaip tai valdyti su Terraform? Yra du pagrindiniai būdai: workspace’ai arba atskirų direktorijų struktūra.
Workspace’ai leidžia naudoti tą patį kodą, bet turėti atskirą state kiekvienai aplinkai. Tai veikia taip:
terraform workspace new development
terraform workspace new staging
terraform workspace new production
terraform workspace select development
terraform apply
Kiekvienas workspace turi savo state failą, todėl galite turėti identiškus resursus skirtingose aplinkose be konfliktų. Kode galite patikrinti, kuriame workspace esate:
locals {
environment = terraform.workspace
instance_type = terraform.workspace == "production" ? "t2.large" : "t2.micro"
}
Tačiau workspace’ai turi trūkumų – sunku matyti, kas egzistuoja kiekvienoje aplinkoje, ir lengva suklysti pasirinkus netinkamą workspace. Todėl daugelis komandų renkasi kitą požiūrį – atskirą direktoriją struktūrą:
project/
├── modules/
│ └── web-server/
├── environments/
│ ├── development/
│ │ └── main.tf
│ ├── staging/
│ │ └── main.tf
│ └── production/
│ └── main.tf
Šis būdas aiškesnis – matote tiksliai, kas yra kiekvienoje aplinkoje, ir neįmanoma atsitiktinai ištrinti production resursų manant, kad esate development aplinkoje. Kiekviena aplinka turi savo state failą ir konfigūraciją.
Saugumo praktikos, kurias privalote žinoti
Terraform saugumas yra kritiškai svarbus, nes jūs valdote visą infrastruktūrą. Viena klaida gali reikšti kompromituotą sistemą ar atsitiktinai ištrintus production resursus. Štai keletas esminių praktikų:
Niekada nekodinkite slaptažodžių tiesiogiai. Vietoj to naudokite:
– AWS Secrets Manager arba Parameter Store
– Azure Key Vault
– HashiCorp Vault
– Aplinkos kintamuosius
Pavyzdys, kaip naudoti AWS Secrets Manager:
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "production/db/password"
}
resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db_password.secret_string
# kita konfigūracija...
}
Naudokite state locking. Tai užkerta kelią situacijai, kai du žmonės vienu metu bando keisti tą pačią infrastruktūrą. Su S3 backend’u tai atrodo taip:
resource "aws_dynamodb_table" "terraform_locks" {
name = "terraform-state-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
Apribokite prieigą prie state failo. State failas turi jautrios informacijos, todėl:
– Naudokite encryption at rest
– Konfigūruokite IAM politikas, kad tik reikalingi žmonės turėtų prieigą
– Įjunkite versioning, kad galėtumėte atkurti ankstesnes versijas
– Reguliariai darykite backup’us
Naudokite terraform plan prieš apply. Tai skamba akivaizdu, bet nustebsite, kiek kartų žmonės praleidžia šį žingsnį ir vėliau gailiisi. Plan parodo tiksliai, kas bus pakeista, ir leidžia pastebėti klaidas prieš darydami žalą.
Automatizavimas su CI/CD pipeline’ais
Tikrasis Terraform galios atsiskleidimas įvyksta, kai integruojate jį į CI/CD pipeline’us. Vietoj to, kad kiekvienas komandos narys rankiniu būdu paleidžia Terraform savo kompiuteryje, viskas vyksta automatiškai per GitLab CI, GitHub Actions, Jenkins ar kitus įrankius.
Štai pavyzdinis GitHub Actions workflow:
name: Terraform
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
- name: Terraform Init
run: terraform init
- name: Terraform Format Check
run: terraform fmt -check
- name: Terraform Validate
run: terraform validate
- name: Terraform Plan
run: terraform plan
- name: Terraform Apply
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: terraform apply -auto-approve
Šis workflow’as daro kelias svarbias užduotis:
– Tikrina kodo formatavimą (`terraform fmt`)
– Validuoja sintaksę (`terraform validate`)
– Rodo planą kiekvienam pull request’ui
– Automatiškai aplikuoja pakeitimus, kai merginama į main branch
Svarbu: `auto-approve` naudokite atsargiai. Geriau reikalauti rankinio patvirtinimo production aplinkose. Galite tai padaryti naudodami GitHub environments su protection rules.
Dar vienas svarbus aspektas – PR komentarai su Terraform plan išvestimi. Tai leidžia revieweriams matyti, kokie infrastruktūros pakeitimai bus padaryti, net jei jie nesupranta Terraform kodo. Galite naudoti įrankius kaip Atlantis arba Terraform Cloud, kurie automatiškai komentuoja PR su plan rezultatais.
Kai viskas sugenda – troubleshooting ir geriausios praktikos
Terraform nėra tobulas, ir kartais viskas eina ne taip, kaip planuota. Štai dažniausios problemos ir kaip jas spręsti:
State drift – tai situacija, kai tikroji infrastruktūra nesutampa su tuo, kas aprašyta state faile. Tai gali nutikti, jei kažkas rankiniu būdu pakeitė resursus konsolėje. Sprendimas: `terraform refresh` atnaujina state failą pagal tikrąją būseną, o `terraform plan` parodys skirtumus.
Dependency problemos. Kartais Terraform bando ištrinti resursą, kuris vis dar naudojamas kito resurso. Naudokite `depends_on` meta-argumentą, kad aiškiai nurodytumėte priklausomybes:
resource "aws_eip" "ip" {
instance = aws_instance.server.id
depends_on = [aws_internet_gateway.gw]
}
Timeout’ai. Kai kurie resursai užtrunka ilgai sukurti (pvz., RDS duomenų bazės). Galite padidinti timeout’us:
resource "aws_db_instance" "main" {
# konfigūracija...
timeouts {
create = "60m"
update = "60m"
delete = "60m"
}
}
Import egzistuojančių resursų. Jei turite infrastruktūrą, sukurtą rankiniu būdu, galite ją importuoti į Terraform:
terraform import aws_instance.example i-1234567890abcdef0
Po import reikia parašyti atitinkamą Terraform kodą, kuris atitiktų importuotą resursą. Tai gali būti varginantis procesas, bet yra įrankiai kaip `terraformer`, kurie gali automatiškai generuoti kodą iš egzistuojančios infrastruktūros.
Dar keletas aukso taisyklių:
– Visada naudokite version constraints proveideriams ir moduliams
– Rašykite aiškius komentarus sudėtingesnėse vietose
– Naudokite `terraform validate` ir `terraform fmt` reguliariai
– Testuokite pakeitimus ne-production aplinkose pirma
– Laikykite Terraform ir providerių versijas atnaujintas, bet ne per agresyviai
Ir pats svarbiausias patarimas: kai kažkas negerai, nepulkite iškart `terraform destroy` ir kurti viską iš naujo. Dažniausiai problemas galima išspręsti tikslingai, o ne atominės bombos metodu. State failą galite redaguoti rankiniu būdu (`terraform state` komandos), bet tai darykite tik kaip paskutinę priemonę ir visada padarykite backup’ą prieš.
Kelionė su Terraform tik prasideda
Terraform infrastruktūros automatizavimas nėra tiesiog dar vienas įrankis jūsų arsenale – tai fundamentalus būdas mąstyti apie infrastruktūrą. Kai pradėsite traktuoti infrastruktūrą kaip kodą, pastebėsite, kad jūsų darbas tampa ne tik efektyvesnis, bet ir maloniau. Nebereikia prisiminti, kokius mygtukus spaudėte prieš šešis mėnesius kurdami serverį. Nebereikia bijoti, kad kolega sukurs kažką kitaip nei jūs. Viskas yra kode, versijuojama, peržiūrima ir atkuriama.
Žinoma, mokymosi kreivė egzistuoja. Pirmosios dienos su Terraform gali būti frustruojančios – kodėl tas planas nesutampa su tuo, ko tikėjausi? Kodėl state failas rodo kažką keisto? Bet kiekviena problema, kurią išsprendžiate, yra pamoka, kuri padaro jus geresniu inžinieriumi. Po kelių savaičių pastebėsite, kad galvojate apie infrastruktūrą kitaip – ne kaip apie rankiniu būdu sukurtus objektus, bet kaip apie deklaratyviai aprašytą būseną.
Pradėkite mažai. Nebandykite iškart migruoti visos savo infrastruktūros į Terraform. Pradėkite nuo vieno projekto, vienos aplinkos. Išmokite pagrindus, padarykite klaidų (geriau development aplinkoje), supaskite, kaip veikia state valdymas. Tada pamažu plėskite. Kurkite modulius, automatizuokite per CI/CD, dalinkitės žiniomis su komanda.
Ir nepamirškite – Terraform bendruomenė yra milžiniška ir draugiška. Terraform Registry pilna paruoštų modulių, kuriuos galite naudoti. Stack Overflow ir HashiCorp forumai pilni žmonių, kurie nori padėti. Dokumentacija, nors kartais gali būti pernelyg techniška, yra išsami ir nuolat atnaujinama.
Infrastruktūros automatizavimas su Terraform – tai ne tikslas, o kelionė. Ir kaip kiekvienoje kelionėje, svarbu ne tik pasiekti tikslą, bet ir mėgautis procesu. Taigi, atidarykite terminalą, sukurkite savo pirmąjį `.tf` failą ir pradėkite eksperimentuoti. Kas gali nutikti blogiausia? Na, galbūt atsitiktinai ištrinsite development serverį, bet tai tik mokymosi dalis. Ir su Terraform jį galėsite atkurti per kelias minutes.
