Зачем это нужно
Предыдущий урок — «зачем IaC». Здесь — как читать и безопасно менять Terraform в команде: variables, outputs, modules, workspaces (или отдельные каталоги env), типичный workflow MR. Даже если вы не platform engineer, вы будете review'ить MR с новым bucket для dataset или quota на namespace через Terraform provider Kubernetes.
Основные идеи
Минимальный root module.
` terraform { required_version = ">= 1.5" required_providers { kubernetes = { source = "hashicorp/kubernetes" version = "~> 2.23" } } backend "s3" { bucket = "mdp-terraform-state" key = "dev/k8s-addons/terraform.tfstate" region = "eu-central-1" } }
provider "kubernetes" { config_path = var.kubeconfig_path }
variable "namespace" { type = string default = "ml-dev" }
resource "kubernetes_namespace" "ml" { metadata { name = var.namespace } } `
Variables и tfvars. Общие defaults в variables.tf; окружение — в dev.tfvars:
namespace = "ml-dev"
terraform plan -var-file=dev.tfvars
Outputs — контракт модуля наружу:
output "namespace_name" { value = kubernetes_namespace.ml.metadata[0].name }
Module call.
` module "minio_tenant" { source = "../modules/minio-tenant"
bucket_name = "ml-datasets-dev" replicas = 4 }
output "bucket" { value = module.minio_tenant.bucket_id } `
Внутри module — свои main.tf, variables.tf, outputs.tf. Версионирование module: git tag или Terraform Registry.
Lifecycle hooks.
` resource "kubernetes_persistent_volume_claim" "example" {
...
lifecycle { prevent_destroy = true } } `
Защита критичных ресурсов от случайного terraform destroy.
Count / for_each. Создать N похожих namespace или S3 prefix:
` variable "teams" { type = list(string) default = ["alpha", "beta"] }
resource "kubernetes_namespace" "team" { for_each = toset(var.teams) metadata { name = "ml-${each.key}" } } `
Plan output читать обязательно.
+ create— новый ресурс~ update in-place— изменение-/+ destroy and recreate— опасно для stateful (PVC, DB)- destroy— удаление
Targeted apply (-target) — только для emergency debug, не для routine (ломает dependency graph).
Как это выглядит на практике
MR workflow в platform team:
Ветка
feat/minio-bucket-ml-capstone.Добавить module call + tfvars для dev.
CI:
terraform fmt -check,validate,plan— comment bot постит plan diff в MR.Review двумя инженерами.
Merge → CD job
terraform applyна dev → smoke → apply prod в maintenance window.
Локально (учебный sandbox только):
cd environments/dev terraform init terraform plan -var-file=dev.tfvars -out=plan.bin terraform apply plan.bin
Kubernetes provider use case для ML. Namespace, ResourceQuota (limits CPU/GPU), LimitRange, optional NetworkPolicy baseline — всё reproducible.
resource "kubernetes_resource_quota" "ml_dev" { metadata { name = "gpu-quota" namespace = "ml-dev" } spec { hard = { "requests.nvidia.com/gpu" = "2" } } }
Типичные ошибки студентов.
Забыли
terraform initпосле clone — provider not found.Правят prod tfvars локально и apply с laptop — обход CI запрещён политикой.
Commit
.tfstateв Git — утечка metadata и secrets.
Что сделать после занятия
Выполните
terraform validateв учебном каталоге (read-only sandbox).Найдите в plan строку
forces replacementи объясните риск для ML workload.Опишите, какие inputs/outputs были бы у module «namespace + quota для capstone team».