Keri sisuni

Terraform Kodutöö: Kohalik Infrastruktuur

Loo kohalik infrastruktuur Terraform'iga. Õpid Infrastructure as Code põhimõtteid praktiliselt - kirjutad koodi mis loob faile ja konfiguratsioone automaatselt. Kodutöö võtab umbes 90 minutit.

Eeldused: Terraform basics labor tehtud, HCL süntaks tuttav
Esitamine: GitHub link Google Classroom'i
Tähtaeg: Kokkulepitud tähtajaks


1. Projekti Ülevaade

Selles kodutöös lood Terraform'iga projekti struktuuri, mis sisaldab kaustu, konfiguratsioonifaile ja skripte. See simuleerib päris elu olukorda, kus uue projekti alustamisel on vaja luua standardne kaustastruktuur.

Käsitsi teeksid seda mkdir ja touch käskudega. Terraform'iga kirjeldad soovitud lõpptulemust koodina - mis failid peavad olemas olema ja mis neis on. Kui käivitad terraform apply, loob Terraform kõik automaatselt. Kui muudad muutujat (nt projekti nime), uuendab Terraform kõik failid.

Lood järgmise struktuuri:

minu-projekt/
├── README.md           # Projekti dokumentatsioon
├── config/
│   ├── project.json    # JSON konfiguratsioon
│   └── app.yaml        # YAML konfiguratsioon
└── scripts/
    └── startup.sh      # Käivitatav skript

2. Failide Loomine

2.1 Projekti Struktuur

Looge kaust ja failid:

mkdir terraform-homework
cd terraform-homework

Looge 4 faili:

  • main.tf - ressursside definitsioonid
  • variables.tf - sisendmuutujad
  • outputs.tf - väljundid
  • terraform.tfvars - muutujate väärtused

2.2 main.tf

See on Terraformi põhifail, kus defineerid ressursid - asjad, mida Terraform loob. Iga resource plokk kirjeldab üht faili: mis sisu seal on ja kuhu see salvestatakse. Terraform loob failid täpselt sellises järjekorras nagu vaja - sa ei pea selle pärast muretsema.

Esimene osa määrab, millist providerit kasutame. Local provider on lihtne - ta loob faile sinu arvutis, ei vaja pilve kontot ega maksekaarti.

terraform {
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "~> 2.0"
    }
  }
}

Järgmised ressursid loovad konfiguratsioonifailid. jsonencode() ja yamlencode() on Terraformi funktsioonid, mis teevad HCL andmestruktuurist JSON/YAML formaadi. See on mugavam kui käsitsi JSON-i kirjutada - Terraform hoolitseb süntaksi eest.

# JSON konfiguratsioon
resource "local_file" "project_config" {
  content = jsonencode({
    project_name = var.project_name
    environment  = var.environment
    version      = "1.0.0"
    created_at   = timestamp()
  })
  filename = "${var.project_name}/config/project.json"
}

# YAML konfiguratsioon
resource "local_file" "app_config" {
  content = yamlencode({
    app = {
      name = var.project_name
      port = 8080
    }
    database = {
      type = "sqlite"
      file = "app.db"
    }
  })
  filename = "${var.project_name}/config/app.yaml"
}

Skriptide loomisel kasutame <<-EOF ... EOF süntaksit, mis võimaldab kirjutada mitmerealist teksti. file_permission = "0755" teeb faili käivitatavaks (nagu chmod +x).

# Startup skript
resource "local_file" "startup_script" {
  content = <<-EOF
    #!/bin/bash
    echo "Tere tulemast ${var.project_name} projekti!"
    echo "Keskkond: ${var.environment}"
    echo ""
    echo "Konfiguratsioon:"
    cat "$(dirname "$0")/../config/project.json"
  EOF
  filename        = "${var.project_name}/scripts/startup.sh"
  file_permission = "0755"
}

# README
resource "local_file" "readme" {
  content = <<-EOF
    # ${var.project_name}

    Projekt loodud Terraform'iga.

    ## Struktuur

    ```
    ${var.project_name}/
    ├── README.md
    ├── config/
    │   ├── project.json
    │   └── app.yaml
    └── scripts/
        └── startup.sh
    ```

    ## Kasutamine

    1. Käivita: `./scripts/startup.sh`
    2. Vaata config: `cat config/project.json`

    ## Info

    - Keskkond: ${var.environment}
    - Loodud: Terraform'iga
  EOF
  filename = "${var.project_name}/README.md"
}

2.3 variables.tf

Muutujad teevad konfiguratsiooni paindlikuks. Selle asemel, et kirjutada "minu-projekt" igale poole otse koodi, kasutad muutujat var.project_name. Kui tahad nime muuta, muudad ühes kohas ja Terraform uuendab kõik failid automaatselt.

validation plokid kontrollivad sisendi õigsust enne kui Terraform midagi teeb. Näiteks ei lase vale keskkonda valida ega liiga lühikest nime panna. See aitab vigu vältida.

variable "project_name" {
  description = "Projekti nimi (kasutatakse kausta nimena)"
  type        = string
  default     = "minu-projekt"

  validation {
    condition     = length(var.project_name) >= 3
    error_message = "Projekti nimi peab olema vähemalt 3 tähemärki."
  }

  validation {
    condition     = can(regex("^[a-z0-9-]+$", var.project_name))
    error_message = "Projekti nimi võib sisaldada ainult väikseid tähti, numbreid ja kriipse."
  }
}

variable "environment" {
  description = "Keskkond (development, staging, production)"
  type        = string
  default     = "development"

  validation {
    condition     = contains(["development", "staging", "production"], var.environment)
    error_message = "Keskkond peab olema: development, staging või production."
  }
}

2.4 outputs.tf

Väljundid näitavad infot pärast terraform apply käivitamist. See on kasulik, et näha, mis failid loodi ja kuhu. Päris infrastruktuuris kasutad väljundeid näiteks serveri IP-aadressi või andmebaasi URL-i kuvamiseks.

output "project_path" {
  description = "Projekti kausta tee"
  value       = var.project_name
}

output "created_files" {
  description = "Loodud failide teed"
  value = {
    readme  = local_file.readme.filename
    config  = local_file.project_config.filename
    yaml    = local_file.app_config.filename
    script  = local_file.startup_script.filename
  }
}

output "environment" {
  description = "Valitud keskkond"
  value       = var.environment
}

2.5 terraform.tfvars

See fail sisaldab muutujate tegelikke väärtusi. Terraform loeb selle faili automaatselt. Kui tahad projekti nime või keskkonda muuta, muudad siin - mitte main.tf failis.

project_name = "minu-projekt"
environment  = "development"

3. Projekti Käivitamine

flowchart LR
    A[terraform init] --> B[terraform plan]
    B --> C{OK?}
    C -->|Jah| D[terraform apply]
    C -->|Ei| E[Paranda koodi]
    E --> B
    D --> F[Kontrolli tulemust]
    F --> G{Muudatused?}
    G -->|Jah| B
    G -->|Valmis| H[terraform destroy]

Nüüd on kõik failid valmis. Terraformi kasutamine käib kolmes etapis: init laeb provideri, plan näitab mida tehakse, apply teeb päriselt.

Käivita Terraform käsud:

# Initsialiseeri (laeb provider'i)
terraform init

Init käsk loob .terraform kausta ja laeb alla local provideri. Seda tuleb teha ainult üks kord projekti alguses.

# Vaata mida tehakse
terraform plan

Plan näitab, mitu ressurssi luuakse ja millised failid tekivad. Siin ei muudeta veel midagi - ainult vaadatakse. Harjuta alati enne apply't plan käivitama.

# Loo failid
terraform apply

Apply küsib kinnitust ("yes") ja loob failid. Pärast näed väljundeid - loodud failide teid.

Kontrolli tulemust:

# Vaata väljundeid
terraform output

# Vaata loodud struktuuri
tree minu-projekt/
# või kui tree pole installitud:
find minu-projekt/ -type f

# Käivita skript
./minu-projekt/scripts/startup.sh

# Vaata JSON konfiguratsioonifaili
cat minu-projekt/config/project.json

# Vaata YAML konfiguratsioonifaili
cat minu-projekt/config/app.yaml

4. Muudatuste Tegemine

Siin näed Terraformi tõelist jõudu. Kui tahad projekti nime muuta, ei pea käsitsi kaustu ümber nimetama ega faile muutma. Muudad ainult muutuja väärtust ja Terraform teeb ülejäänu.

Muuda terraform.tfvars:

project_name = "uus-projekt"
environment  = "production"

Rakenda muudatused:

terraform plan    # Näitab: kustutatakse vanad, luuakse uued
terraform apply

Plan väljundis näed punast teksti (kustutatakse) ja rohelist (luuakse). Terraform mõistab, et failiteed muutusid ja peab vanad failid kustutama ning uued looma. See on deklaratiivse lähenemise võlu - sa kirjeldad soovitud lõppseisu ja Terraform väljastab sammud sinna jõudmiseks.


5. Lisaülesanne: Cleanup Skript

Nüüd lisad olemasolevale projektile uue ressursi. See näitab, kuidas Terraform käsitleb muudatusi - ta ei loo kõike uuesti, vaid lisab ainult puuduva.

Lisa main.tf faili lõppu veel üks ressurss:

# Cleanup skript
resource "local_file" "cleanup_script" {
  content = <<-EOF
    #!/bin/bash
    echo "Puhastan ${var.project_name}..."
    cd "$(dirname "$0")/.."
    rm -f *.tmp *.log *.bak
    echo "Ajutised failid kustutatud!"
  EOF
  filename        = "${var.project_name}/scripts/cleanup.sh"
  file_permission = "0755"
}

Lisa outputs.tf faili created_files outputi uus rida:

output "created_files" {
  description = "Loodud failide teed"
  value = {
    readme  = local_file.readme.filename
    config  = local_file.project_config.filename
    yaml    = local_file.app_config.filename
    script  = local_file.startup_script.filename
    cleanup = local_file.cleanup_script.filename  # Lisa see rida
  }
}

Rakenda ja testi:

terraform plan   # Näitab: 1 to add (ainult cleanup.sh)
terraform apply
./minu-projekt/scripts/cleanup.sh

Pane tähele, et plan näitab "1 to add" - Terraform teab, et teised failid on juba olemas ja lisab ainult uue.


6. Puhastamine

Kui oled lõpetanud, saad Terraformiga kõik loodud ressursid kustutada. See on oluline oskus - päris infrastruktuuris ei taha sa maksta ressursside eest, mida enam ei kasuta.

terraform destroy

Terraform näitab, mida kavatseb kustutada ja küsib kinnitust. Kirjuta "yes" ja kõik Terraformi loodud failid kustutatakse.

Tühjad kaustad võivad jääda alles - Terraform haldab ainult faile, mitte kaustu. Kustuta need käsitsi kui soovid:

rm -rf minu-projekt/

Esitamine

Kontroll Enne Esitamist

  • Kõik 4 Terraform faili on loodud (main.tf, variables.tf, outputs.tf, terraform.tfvars)
  • terraform init töötab
  • terraform plan näitab 4+ ressurssi
  • terraform apply loob struktuuri ilma vigadeta
  • Loodud failide struktuur on õige:
minu-projekt/
├── README.md
├── config/
│   ├── project.json
│   └── app.yaml
└── scripts/
    └── startup.sh
  • Skript käivitub: ./minu-projekt/scripts/startup.sh
  • terraform output näitab loodud failide teid
  • Muutujate muutmine ja uuesti apply töötab
  • Lisaülesanne tehtud (cleanup skript)
  • terraform destroy kustutab failid
  • Kõik failid on GitHub'is

GitHub Repository

# Lisa .gitignore ENNE commitimist
cat > .gitignore << 'EOF'
# Terraform
.terraform/
*.tfstate
*.tfstate.*
.terraform.lock.hcl

# Loodud projekt (see on output, mitte source)
minu-projekt/
uus-projekt/
EOF

# Initsialiseeri ja commit
git init
git add .
git commit -m "Terraform homework - local infrastructure"
git branch -M main
git remote add origin https://github.com/[sinu-kasutaja]/terraform-homework.git
git push -u origin main

Esitamine Google Classroom'i

Esita oma GitHub repository link Google Classroom'i. Veendu, et repository on avalik (public) või anna õpetajale ligipääs.


Refleksioon

Vasta küsimustele (2-3 lauset igaüks):

  1. Mis oli kõige lihtsam osa Terraform'i juures?

[Sinu vastus]

  1. Mis oli keerulisem kui arvasid?

[Sinu vastus]

  1. Kuidas Infrastructure as Code erineb käsitsi failide loomisest?

[Sinu vastus]

  1. Kus saaksid seda päris töös kasutada?

[Sinu vastus]

  1. Mida tahaksid järgmisena Terraform'i kohta õppida?

[Sinu vastus]


Hindamiskriteeriumid

Kriteerium Punktid Kirjeldus
Põhifunktsioonid 60%
- Terraform failid olemas 15% main.tf, variables.tf, outputs.tf, terraform.tfvars
- Terraform töötab 15% init, plan, apply käsud töötavad
- Failide struktuur õige 15% config/, scripts/, README.md
- Skript käivitub 15% startup.sh töötab
Kood 20%
- Variables kasutatud 10% Muutujad on eraldi failis
- Outputs defineeritud 10% Näitab loodud failide teid
Dokumentatsioon 20%
- README selge 10% Selgitab mis ja kuidas
- Refleksioon täidetud 10% Vastused on mõtestatud
Boonus +10%
- Cleanup skript +5% Lisaülesanne tehtud
- Production backup +5% Tingimuslik ressurss

Boonus (+10%)

1. Cleanup Skript (+5%)

Kui tegid lisaülesande (sektsioon 5), saad 5% boonust.

2. Production Backup Skript (+5%)

See ülesanne õpetab tingimuslikku ressursi loomist. Mõnikord tahad, et teatud ressurss eksisteeriks ainult teatud tingimustel - näiteks backup skript ainult production keskkonnas, sest development'is pole seda vaja.

count argument koos tingimusega teeb seda: kui count = 1, siis ressurss luuakse; kui count = 0, siis mitte.

Lisa main.tf faili ressurss mis loob backup skripti ainult production keskkonnas:

# Backup skript - ainult production keskkonnas
resource "local_file" "backup_script" {
  count = var.environment == "production" ? 1 : 0

  content = <<-EOF
    #!/bin/bash
    echo "Backup käivitatud: $(date)"
    tar -czf backup-$(date +%Y%m%d).tar.gz config/
    echo "Backup loodud!"
  EOF
  filename        = "${var.project_name}/scripts/backup.sh"
  file_permission = "0755"
}

Kui tahad backup faili ka outputs'is näidata, lisa outputs.tf faili:

output "backup_script" {
  description = "Backup skripti tee (ainult production)"
  value       = try(local_file.backup_script[0].filename, null)
}

try() funktsioon tagastab null kui ressurssi ei eksisteeri (st development/staging keskkonnas). Ilma try() funktsioonita saaksid vea, sest count = 0 korral ei ole backup_script[0] olemas.

Testi:

# Development - backup.sh EI looda
terraform apply -var="environment=development"
ls minu-projekt/scripts/  # ainult startup.sh

# Production - backup.sh luuakse
terraform apply -var="environment=production"
ls minu-projekt/scripts/  # startup.sh JA backup.sh

Abi ja Troubleshooting

"Error: Could not load plugin"

terraform init

"Error creating file: no such directory"

Local provider loob kataloogid automaatselt. Kui siiski viga, kontrolli et project_name ei sisalda keelatud märke.

Permission denied skripti käivitamisel

chmod +x minu-projekt/scripts/startup.sh

Terraform destroy ei kustuta kaustu

Terraform kustutab ainult failid, mitte tühje kaustu. Kustuta käsitsi:

rm -rf minu-projekt/

Vale keskkond valitud

terraform apply -var="environment=development"
# või muuda terraform.tfvars faili

Edu kodutööga!