Terraform (Инструмент управления состоянием инфраструктуры)

⌘K

Terraform (Инструмент управления состоянием инфраструктуры)

Terraform — это фреймворк для управления инфраструктурой как кодом (IaC), разработанный компанией HashiCorp. Он позволяет описывать, создавать, изменять и удалять ресурсы в облачных, локальных и гибридных средах с помощью декларативного синтаксиса.

Конфигурации в Terraform пишутся на языке HCL (HashiCorp Configuration Language) — простом, читаемом формате, близком к YAML, но ориентированном на инфраструктурные сценарии. Код хранится в .tf-файлах, где описываются все необходимые компоненты: от виртуальных машин и сетей до баз данных, DNS-записей и политик доступа.

Ключевые принципы работы Terraform:

  1. Declarative — ты описываешь, что должно быть, а не как это сделать.
  2. Plan — перед применением Terraform показывает, какие изменения будут сделаны.
  3. Apply — на этом этапе ресурсы создаются или изменяются.
  4. State — текущее состояние инфраструктуры хранится в виде файла (terraform.tfstate), который используется для расчёта дельты при следующих изменениях.
  5. Idempotent — повторное применение кода не приводит к повторному созданию ресурсов, если ничего не изменилось.

Пример использования:

С помощью Terraform можно за одну операцию:

  • создать VPC и подсети в AWS,
  • развернуть EC2-инстансы с нужным образом,
  • задать правила firewall’а (Security Groups),
  • настроить IAM-политики и роли,
  • автоматически подключить всё к балансировщику.

Поддержка облаков и провайдеров:

Terraform работает через провайдеры (providers), каждый из которых знает, как управлять тем или иным API. Поддерживаются:

Почему Terraform стал стандартом:

  • 💡 Прозрачность — можно видеть, какие изменения будут сделаны, до их применения.
  • 🔁 Повторяемость — та же конфигурация применима к любому окружению (dev, staging, prod).
  • 🔐 Контроль версий — код хранится в Git, можно отслеживать, сравнивать и откатывать изменения.
  • 🤝 Совместимость с CI/CD пайплайнами, GitOps-подходом, политиками безопасности и тестами (tflint, checkov, OPA).

Terraform широко используется в DevOps, SRE и платформенных командах, где важно быстро и безопасно управлять масштабируемой инфраструктурой — особенно в мультиоблачной или гибридной архитектуре.


📁 Пример Terraform-модуля: EC2-инстанс с переменными

📁 Структура проекта:

terraform-project/
├── main.tf
├── variables.tf
├── outputs.tf
├── terraform.tfvars
└── modules/
    └── ec2-instance/
        ├── main.tf
        ├── variables.tf
        └── outputs.tf

🔧 main.tf (корень проекта):

provider "aws" {
  region = "us-east-1"
}

module "web_server" {
  source        = "./modules/ec2-instance"
  instance_name = "frontend-node"
  instance_type = "t3.micro"
  ami_id        = "ami-0c55b159cbfafe1f0"
}

🧩 modules/ec2-instance/main.tf:

resource "aws_instance" "this" {
  ami           = var.ami_id
  instance_type = var.instance_type

  tags = {
    Name = var.instance_name
  }
}

📥 modules/ec2-instance/variables.tf:

variable "instance_name" {
  description = "Name tag for the EC2 instance"
  type        = string
}

variable "instance_type" {
  description = "Type of EC2 instance"
  type        = string
  default     = "t2.micro"
}

variable "ami_id" {
  description = "AMI ID for the instance"
  type        = string
}

📤 modules/ec2-instance/outputs.tf:

output "instance_id" {
  value = aws_instance.this.id
}

output "public_ip" {
  value = aws_instance.this.public_ip
}

📦 terraform.tfvars (значения по умолчанию):

instance_type = "t3.micro"
ami_id        = "ami-0c55b159cbfafe1f0"

💡 Что делает этот модуль:

  • Разворачивает EC2-инстанс с заданной AMI и типом.
  • Использует переиспользуемую логику из подкаталога modules/ec2-instance.
  • Передаёт значения через переменные.
  • Отдаёт ID и публичный IP-адрес инстанса через outputs.

Такой подход позволяет:

  • легко масштабировать инфраструктуру;
  • переиспользовать один модуль в разных окружениях;
  • передавать значения через .tfvars или переменные окружения;
  • подключать в CI/CD пайплайны и GitOps-сценарии.

☁️ Хранение состояния: remote backend (S3 + DynamoDB)

Чтобы несколько человек или CI-система могли безопасно работать с Terraform-проектом, рекомендуется хранить terraform.tfstate в удалённом хранилище. Пример с AWS:

📄 backend.tf (можно объединить с main.tf):

terraform {
  backend "s3" {
    bucket         = "my-terraform-state-bucket"
    key            = "envs/dev/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-lock-table"
    encrypt        = true
  }
}

🔒 DynamoDB используется для блокировок и предотвращает одновременное применение (terraform apply) из двух мест.


🔎 Пример data source: получение последнего AMI

Terraform позволяет подтягивать данные без создания ресурсов.

data "aws_ami" "latest_amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

Потом можно использовать:

ami = data.aws_ami.latest_amazon_linux.id

📦 Terraform + Helm (для управления Kubernetes)

Для развёртывания Helm-чартов прямо из Terraform используют Helm provider.

provider "helm" {
  kubernetes {
    config_path = "~/.kube/config"
  }
}

resource "helm_release" "nginx" {
  name       = "nginx"
  repository = "https://charts.bitnami.com/bitnami"
  chart      = "nginx"
  version    = "15.2.0"

  set {
    name  = "service.type"
    value = "LoadBalancer"
  }
}

✅ Преимущества такой связки:

  • Один terraform apply создаёт кластер (через aws_eks_cluster) и тут же устанавливает Helm-чарты.
  • Всё версионируется, управляется кодом и полностью автоматизируется.
  • Можно динамически передавать значения между модулями и чартами.