Terraform — это фреймворк для управления инфраструктурой как кодом (IaC), разработанный компанией HashiCorp. Он позволяет описывать, создавать, изменять и удалять ресурсы в облачных, локальных и гибридных средах с помощью декларативного синтаксиса.
Конфигурации в Terraform пишутся на языке HCL (HashiCorp Configuration Language) — простом, читаемом формате, близком к YAML, но ориентированном на инфраструктурные сценарии. Код хранится в .tf-файлах, где описываются все необходимые компоненты: от виртуальных машин и сетей до баз данных, DNS-записей и политик доступа.
Ключевые принципы работы Terraform:
- Declarative — ты описываешь, что должно быть, а не как это сделать.
- Plan — перед применением Terraform показывает, какие изменения будут сделаны.
- Apply — на этом этапе ресурсы создаются или изменяются.
- State — текущее состояние инфраструктуры хранится в виде файла (
terraform.tfstate), который используется для расчёта дельты при следующих изменениях. - Idempotent — повторное применение кода не приводит к повторному созданию ресурсов, если ничего не изменилось.
Пример использования:
С помощью Terraform можно за одну операцию:
- создать VPC и подсети в AWS,
- развернуть EC2-инстансы с нужным образом,
- задать правила firewall’а (Security Groups),
- настроить IAM-политики и роли,
- автоматически подключить всё к балансировщику.
Поддержка облаков и провайдеров:
Terraform работает через провайдеры (providers), каждый из которых знает, как управлять тем или иным API. Поддерживаются:
- AWS, Azure, Google Cloud, Alibaba Cloud;
- Kubernetes, Helm, Cloudflare, GitHub, Datadog, Vault, vSphere и сотни других.
Почему 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-чарты. - Всё версионируется, управляется кодом и полностью автоматизируется.
- Можно динамически передавать значения между модулями и чартами.